ユーザーが差し込み印刷対応の Word DOCX テンプレート ファイルをアップロードできるようにするソリューションを考え出そうとしています。理想的には、システムが DOCX ファイルを読み取り、XML を抽出し、差し込み印刷フィールドを見つけて、後でマッピングするためにそれらをデータベースに保存します。Zend LiveDocX や PHPDOCX などの SOAP サービスを使用することもできますが、今のところ、DOCX ファイル内のフィールドを識別する方法を理解する必要があります。そのために、私はこの記事から始めました: http://dfmaxwell.wordpress.com/2012/02/24/using-php-to-process-a-word-document-mail-merge/
私は自分のニーズに合わせて少し調整しました (元のコードでも同じエラーが発生しますが、これは問題になる可能性があります)。具体的には、現時点では差し込み印刷を実行するために使用していません。フィールドを識別します。これが私が持っているものです:
$newFile = '/var/www/mysite.com/public_html/template.docx';
$zip = new ZipArchive();
if( $zip->open( $newFile, ZIPARCHIVE::CHECKCONS ) !== TRUE ) { echo 'failed to open template'; exit; }
$file = 'word/document.xml';
$data = $zip->getFromName( $file );
$zip->close();
$doc = new DOMDocument();
$doc->loadXML( $data );
$wts = $doc->getElementsByTagNameNS('http://schemas.openxmlformats.org/wordprocessingml/2006/main', 'fldChar');
$mergefields = array();
function getMailMerge(&$wts, $index) {
$loop = true;
$counter = $index;
$startfield = false;
while ($loop) {
if ($wts->item($counter)->attributes->item(0)->nodeName == 'w:fldCharType') {
$nodeName = '';
$nodeValue = '';
switch ($wts->item($counter)->attributes->item(0)->nodeValue) {
case 'begin':
if ($startfield) {
$counter = getMailMerge($wts, $counter);
}
$startfield = true;
if ($wts->item($counter)->parentNode->nextSibling) {
$nodeName = $wts->item($counter)->parentNode->nextSibling->childNodes->item(1)->nodeName;
$nodeValue = $wts->item($counter)->parentNode->nextSibling->childNodes->item(1)->nodeValue;
}
else {
// No sibling
// check next node
$nodeName = $wts->item($counter + 1)->parentNode->previousSibling->childNodes->item(1)->nodeName;
$nodeValue = $wts->item($counter + 1)->parentNode->previousSibling->childNodes->item(1)->nodeValue;
}
if (substr($nodeValue, 0, 11) == ' MERGEFIELD') {
$mergefields[] = strtolower(str_replace('"', '', trim(substr($nodeValue, 12))));
}
$counter++;
break;
case 'separate':
$counter++;
break;
case 'end':
if ($startfield) {
$startfield = false;
}
$loop = false;
}
}
}
return $counter;
}
for ($x = 0; $x < $wts->length; $x++) {
if ($wts->item($x)->attributes->item(0)->nodeName == 'w:fldCharType' && $wts->item($x)->attributes->item(0)->nodeValue == 'begin') {
$newcount = getMailMerge($wts, $x);
$x = $newcount;
}
}
ZipArchive() を使用して DOCX ファイルを開くのに問題はありません。 print_r($doc->saveHTML()); を使用すると、XML データは正常に表示されます。問題は、コードを実行すると致命的なエラーが発生することです。これを指す非オブジェクトのメンバー関数 item() への呼び出し:
$nodeName = $wts->item($counter)->parentNode->nextSibling->childNodes->item(1)->nodeName;
このエラーを理解しようとしているときに Google は私を失望させました。誰かが私を正しい方向に向けることができますか? 前もって感謝します!