PHPWordを使ってPHPで日本語Word文書を出力する

PHPWordを使うとWord2007以降で使われているdocx形式のWord文書を扱うことができます。これを利用してWord文書のテンプレートを読み込んで、値を埋めて出力することができます。よくある帳票処理に使えます。また、Win32OLEを経由しないのでLinuxでも動きます。

Wordテンプレートに日本語を埋め込む

PHPWordのExampleフォルダにTemplate.phpがあるのでこれをコマンドプロンプトなりで実行してみましょう。うまく動いたら置き換える文字列を日本語にして実行してみます。

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

$PHPWord = new PHPWord();

$document = $PHPWord->loadTemplate('Template.docx');

$document->setValue('Value1', '太陽');
$document->setValue('Value2', '水星');
$document->setValue('Value3', '火星');
$document->setValue('Value4', 'Earth');
$document->setValue('Value5', 'Mars');
$document->setValue('Value6', 'Jupiter');
$document->setValue('Value7', 'Saturn');
$document->setValue('Value8', 'Uranus');
$document->setValue('Value9', 'Neptun');
$document->setValue('Value10', 'Pluto');

$document->setValue('weekday', date('l'));
$document->setValue('time', date('H:i'));

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

はい、化けました。

フォーラムの記事を参考にPHPWord/Template.phpのsetValue()からutf8_encodeをコメントアウトします。

<?php
    public function setValue($search, $replace) {
        if(substr($search, 0, 2) !== '${' && substr($search, -1) !== '}') {
            $search = '${'.$search.'}';
        }
        /*
        if(!is_array($replace)) {
            $replace = utf8_encode($replace);
        }
        */
        $this->_documentXML = str_replace($search, $replace, $this->_documentXML);
    }
?>

今度はうまくいきました。

置換対象文字列を書くときの注意

PHPWordでやってる文字列置換というのが、OpenXML上の文字列をそのまま置換してるだけなのでOpen XML上で文字が離れてしまうと置換されなくなります。

例えば ${Value4} を ${Value3} に数字の部分だけ書き換えると↓のように文字が離れてしまい置換されなくなります。これで半日無駄にしました…。

一旦消してから1入力で${Value3}と入力すればOKです。

ちなみにOpen XMLの中身を見るには、private $_documentXML; の宣言をpublicにするか、getterを用意するなどして、var_dump($document->_documentXML); すると見えます。

参考サイト

PHPWord
http://phpword.codeplex.com/
East Asian characters appears wrongly
http://phpword.codeplex.com/workitem/8