PHPWordで文書生成
文書を自動生成しようとして、そう言えばPHPExcelってあったよなと思って探していると、PHPWordというものも存在していることを知る(開発は2011年で止まっている)。
とりあえず、練習文書を作成してみようとすると、(紹介ページにあるとおり)日本語が文字化けしてしまってきちんと文書生成ができない。
- PHPWord Wordファイルの作成 – PHPJP
- utf8_encode()を使った変換をやめます。
- PHPWordを使ってPHPで日本語Word文書を出力する – mikage014の日記
- [php]PHPWordのテンプレートで改行を含む文字列をsetValueで追加する | ブログ | そうだ車輪と名づけよう 5th
PHPWordの内部で使われているutf8_encode()関数が悪さをしているらしく、該当箇所を探すと21件件出てきた。
$ grep -r -n utf8_encode ../PHPWord.php . | cat -n 1 ../PHPWord.php:35:runkit_function_remove('utf8_encode'); 2 ../PHPWord.php:36:runkit_function_add('utf8_encode', '$text', 'echo $text."\n"; return mb_convert_encoding($text, "utf8", "auto");'); 3 ./Section/Footer.php:75: $givenText = utf8_encode($text); 4 ./Section/Footer.php:165: $text = utf8_encode($text); 5 ./Section/TextRun.php:83: $givenText = utf8_encode($text); 6 ./Section/TextRun.php:98: $linkSrc = utf8_encode($linkSrc); 7 ./Section/TextRun.php:100: $linkName = utf8_encode($linkName); 8 ./Section/Table/Cell.php:111: $text = utf8_encode($text); 9 ./Section/Table/Cell.php:127: $linkSrc = utf8_encode($linkSrc); 10 ./Section/Table/Cell.php:129: $linkName = utf8_encode($linkName); 11 ./Section/Table/Cell.php:163: $text = utf8_encode($text); 12 ./Section/Table/Cell.php:272: $text = utf8_encode($text); 13 ./Section/Header.php:75: $givenText = utf8_encode($text); 14 ./Section/Header.php:165: $text = utf8_encode($text); 15 ./Shared/String.php:150: return utf8_encode(utf8_decode($value)) === $value; 16 ./Section.php:112: $givenText = utf8_encode($text); 17 ./Section.php:128: $linkSrc = utf8_encode($linkSrc); 18 ./Section.php:130: $linkName = utf8_encode($linkName); 19 ./Section.php:182: $text = utf8_encode($text); 20 ./Section.php:290: $text = utf8_encode($text); 21 ./Template.php:89: $replace = utf8_encode($replace);
utf8_encode()自体はphp標準関数なのだが、utf8といってもISO-8859-1のLatin-1と呼ばれるものにしか対応していないため、文字化けを起こしているのらしい。
呼ばれ方は、基本的に「$X = utf8_encode($X)」という形式なので、呼び出したくなければその行をコメントアウトすればいいのだが、ところどころ「$givenText = utf8_encode($text)」という風に単にコメントアウトでは対応できなさそうな個所もある。また、先の紹介ページでは、該当箇所でutf8_encode()を削除すれば(関数呼び出しを外せば)いいという対応もあるのだが、複数個所存在するし対応抜けやらバージョンが更新された場合(は、当分実現しそうにないが)の対応などが面倒かと考えて、この関数自体をmb_convert_encoding()に置き換えればいいのではないか、と考えたのだが、そこからが長かった…。