web-dev-qa-db-ja.com

PHPWordでテンプレートを操作する

開発中のWebアプリのレポートモジュールにPHP)のWordドキュメントジェネレーターを使用しています。無料バージョンのPHPDocXの機能は非常に限られており、フッターもあるため、PHPWordを選択します。これは無料バージョンのみです。クライアントから提供されたテンプレートがあります。必要なのは、テンプレートをロードして、追加のテキストやテーブルなどの動的要素を追加したいことです。コードは次のとおりです。

<?php
require_once '../PHPWord.php';

$PHPWord = new PHPWord();

$document = $PHPWord->loadTemplate('Template.docx');
$document->setValue('Value1', 'Great');

$section = $PHPWord->createSection();
$section->addText('Hello World!');
$section->addTextBreak(2);

$document->setValue('Value2', $section);

$document->save('test.docx');
?>

新しいセクションを作成して、それをテンプレート(Value2)の1つの変数に割り当てようとしましたが、このエラーが表示されました:

[28-Jan-2013 10:36:37 UTC] PHP Warning:  utf8_encode() expects parameter 1 to be string, object given in /Users/admin/localhost/PHPWord_0.6.2_Beta/PHPWord/Template.php on line 99

setValueは、2番目のパラメーターがプレーンな文字列であることを想定しています。セクションオブジェクトを提供することはできません。

コードを詳しく調べましたが、setValue関数で使用できる値をセクションオブジェクトに返す簡単な方法はありません。

同じ問題が発生したため、タグをsetValueに置き換える前に、テーブルの行のクローンを作成できるTemplate.phpファイルのパッチを作成しました。各行は一意のIDを取得し、異なる行ごとにテンプレートタグを識別できるようにします。

これがその仕組みです:

この関数をTemplate.phpファイル(PHPWordディレクトリ内にあります)に追加します

public function cloneRow($search, $numberOfClones) {
    if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
        $search = '${'.$search.'}';
    }
    $tagPos      = strpos($this->_documentXML, $search);
    $rowStartPos = strrpos($this->_documentXML, "<w:tr", ((strlen($this->_documentXML) - $tagPos) * -1));
    $rowEndPos   = strpos($this->_documentXML, "</w:tr>", $tagPos) + 7;

    $result = substr($this->_documentXML, 0, $rowStartPos);
    $xmlRow = substr($this->_documentXML, $rowStartPos, ($rowEndPos - $rowStartPos));
    for ($i = 1; $i <= $numberOfClones; $i++) {
        $result .= preg_replace('/\$\{(.*?)\}/','\${\\1#'.$i.'}', $xmlRow);
    }
    $result .= substr($this->_documentXML, $rowEndPos);
    $this->_documentXML = $result;
}

テンプレートファイルで、テンプレート行として使用する1つの行を各テーブルに追加します。この行にタグ$ {first_name}を追加したとしましょう。

3行のテーブルを取得するには、次のように呼び出します。$ document-> cloneRow( 'first_name'、3);

テンプレートの作業コピーが、3行を含むテーブルで更新されました。行内の各タグには、#と行番号が追加されています。

値を設定するには、setValue $ document-> setValue( 'first_name#1'、 '最初の行の名前');を使用します。 $ document-> setValue( 'first_name#2'、 '2行目の名前'); $ document-> setValue( 'first_name#3'、 '3行目の名前');

これがお役に立てば幸いです。コードとドキュメントの更新バージョンをここに保持します: http://jeroen.is/phpword-templates-with-repeating-rows/

6
Jeroen Moors

ドキュメントによると、テンプレートを使用している場合、ファイルにコンテンツを追加することはできません。

ロードされたテンプレートファイルに新しいPHPWord要素を追加することはできません。

ドキュメント

まったく新しいバージョンのCloneRowとsetValue

これで、マージされたセルのクローンを作成できます。 OOXMLタグの多くのバグが修正されました。

そして、新しいメソッドsetValue-パターン内のごみタグを無視するようになりました。お気に入り

{My<trash ooxml tags>Pattern}

コード、ドキュメント、例はここにあります: https://github.com/Arisse/PHPWord_CloneRow

1
Korimizu