mpdfというライブラリを使うと、プログラム言語PHPを使ってHTML形式でPDFファイルを作成することができます。実際に仕事でも使っているのですが、特定の日本語の場合、文字がおかしくなる現象がありました。
そこで今回は簡単なコードでmpdfを使ったPDFの作り方と日本語フォントの指定方法について書きます。割と簡単ですので初心者の方も試してみてください。
こんなサンプルプログラムを作ってみます
今回はサンプルとして申込書をPDFとして出力できるようにしてみます。
・申込用紙はExcelで作って保存(moushikomi.pdf)
・申込用紙にプログラムによって、内容(氏名、住所など)を上書きする
というような仕様です。プログラムはPDFファイルを下敷きとして読み込んで、氏名や住所などの内容をプログラムで出力するというものです。
Excelは
こんな感じに作って、通常保存したほかに、名前を付けて保存で
こんな感じにPDFで保存しておきます。
実際にプログラムを作るときはこの氏名や住所はWebサイトの申し込みフォームなどから入力した値を使ったり、データベースなどのデータから出力することになりますがそこまでサンプルPHPで書いてしまうと非常に長くなってしまうため、今回はPDFをどのように出力するかというところだけを具体的に記述しています。
氏名や住所などの値はPHPソースに直書きとなりますが、実際にはここにWebサイトの申し込みフォームなどから入力した値を使ったり、データベースなどのデータを入れるようなプログラムとなると思われます。
このプログラムはphptest というフォルダに moushikomi_print.php というプログラムを作ってそれを実行すると、申込書PDFが画面に表示されるようにします。moushikomi.pdf もこのphptest というフォルダに入れることになります。
mpdfライブラリのダウンロード
mpdfとはPDFから簡単なコードとHTMLでPDFファイルを出力できるライブラリです。
ダウンロードは
http://www.mpdf1.com/mpdf/index.php?page=Download
こちらから行うことができます。
mPDF version 6.0 をクリック。MPDF_6_0.zip というファイルがダウンロードされるので解凍します。
MPDF_6_0 というフォルダの中に mpdf60 というフォルダが入っています。
このフォルダをPDFファイルを作るPHPを置く場所から参照できるところに移動します。今回はプログラムを置いてあるphptest フォルダに移動しました。
プログラムは moushikomi_print.php という名前で作りますので、最終的にphptest フォルダの内容はこんな感じとなります。
mpdfを使ってPDFを作るプログラムを書く
mpdfを使ってPDFを作るPHPプログラムはこのようなコードになります。
<? // 申込書をmpdfで出力する // mpdfライブラリ include("mpdf60/mpdf.php"); $mpdf=new mPDF('ja', 'A4'); // utf8でエラーが起こらないようにする $mpdf->ignore_invalid_utf8 = true; // PDFをインポートして下敷きとして使うための設定 $mpdf->SetImportUse(); // 下敷きのPDFを読み込む pagecountにはページ数が入る $pagecount = $mpdf->SetSourceFile("moushikomi.pdf"); // この場合は1ページしかないので1ページ目をテンプレートとして指定 $tplId = $mpdf->ImportPage(1); $mpdf->SetPageTemplate($tplId); // ページに値を埋め込む $mpdf->WriteHTML('<div style="position:relative;"'); // 内容用のDIVテンプレート $tempDiv = '<div style="width:430px;position:absolute;top:%spx;left:%spx;font-size:%s;white-space: nowrap;">%s</div>'; // 各項目のセット $mpdf->WriteHTML(sprintf($tempDiv, 155, 220, '1.3rem', '2016年7月13日')); $mpdf->WriteHTML(sprintf($tempDiv, 215, 220, '1.3rem', '山本尚子')); $mpdf->WriteHTML(sprintf($tempDiv, 275, 220, '1.3rem', 'naoko@example.com')); $mpdf->WriteHTML(sprintf($tempDiv, 335, 220, '1.3rem', '〒100-0011 東京都千代田区内幸町1-1-1 千代田ビル503')); $mpdf->WriteHTML(sprintf($tempDiv, 470, 220, '1.3rem', '00-9999-6666')); $mpdf->WriteHTML(sprintf($tempDiv, 530, 220, '1.3rem', 'WordPressのインストール<br /> ホームページ作成と公開')); $mpdf->WriteHTML('</div>'); // PDFを出力 $mpdf->Output();
このように短いPHPプログラムです。内容はmpdfライブラリの準備、下敷き(moushikomi.pdf)の準備、HTMLの編集、pdfの出力です。
各項目のセットはHTMLの形式が共通でしたので $tempDiv でテンプレートを作っておいて、sprintfでそれぞれに違う部分だけを置き換えています。
$mpdf->WriteHTML(sprintf($tempDiv, 155, 220, '1.3rem', '2016年7月13日'));
は
$mpdf->WriteHTML('<div style="width:430px;position:absolute;top:155px;left:220px;font-size:1.3rem;white-space: nowrap;">2016年7月13日</div>');
このように指定したのと同じことになります。
mpdfを使ってPDFを作るプログラムを実行してみる
このプログラムをブラウザで実行してみます。
このように下敷きとして作ったpdfの上にプログラムで指定した各項目の内容がうまく挿入されています(^^)/。
ここから
pdfファイルとして保存したり、印刷したりすることができます。
一部の文字がおかしくなる問題と原因、その解決方法
日本語もちゃんと表示されているし問題ない、と思ったのですがたくさんのデータを出力すると、一部の文字がおかしいことに気づきました。名前をおかしな文字をまとめた架空の名前に置き換えてみます。
$mpdf->WriteHTML(sprintf($tempDiv, 215, 220, '1.3rem', '浅坂直子'));
これでプログラムを実行すると
このように 浅 という字の横棒が3本のはずが2本、坂という文字の 反 の上の棒が斜めになっている、 直 という字がだいぶおかしい(^_^; というようにおかしなことになっています。
ひらがなもきれいに出ていたし、いったいなぜ???としばらくわかりませんでしたが、検索して
こちらのページでやっとわかりました。mpdfはcssなどで各PCに入っているフォントを使う方法(一般的なHTMLなどではこの方法)ではなく埋め込みフォント(mpdfに入っているフォントデータを利用する)を使っています。これは申込書など用紙の枠が決まっているようなときにどの環境でも同じように枠の中に入れるにはどの環境でも同じフォントが使われないとまずいため、だと思います。
今回日本語に対応して使われているのは cjkフォント というものでした。
CJK統合漢字の名称は、中国語、日本語、朝鮮語で使われている漢字をひとまとめにしたことからきている。
とあるように中国語、日本語、朝鮮語で同じフォントを使えるようにしたものらしいです。しかし、参考にしたblog記事にあったように、すべての日本語が正しく出るわけでなく一部の文字がおかしい表示になってしまうようでした。
とういことで、cjkフォントに指定されているフォントデータ自体を置き換えたいと思います。
Webフォントとして利用可能なIPAフォントから、今回利用したい明朝体のttfファイルをダウンロードします。
*ライセンスについては http://ipafont.ipa.go.jp/node87#q005-1 参照
http://ipafont.ipa.go.jp/old/ipafont/download.html
こちらのページの
ipamp00303.zip をクリックしてダウンロード。ダウンロードしたファイルを解凍して、ipamp00303\ipamp00303\ にある
ipamp.ttf をコピーします。これを、phptest\mpdf60\ttfonts\ に貼り付けます。
cjkフォントでIPAフォントを利用できるようにするには、
phptest\mpdf60\config_fonts.php を開いて、
/* CJK fonts */ "sun-exta" => array( 'R' => "Sun-ExtA.ttf", 'sip-ext' => 'sun-extb', /* SIP=Plane2 Unicode (extension B) */ ), "sun-extb" => array( 'R' => "Sun-ExtB.ttf", ), "unbatang" => array( /* Korean */ 'R' => "UnBatang_0613.ttf", ),
とあるところの Sun-ExtA.ttf を ipamp.ttf に置き換えます。
/* CJK fonts */ "sun-exta" => array( 'R' => "ipamp.ttf", 'sip-ext' => 'sun-extb', /* SIP=Plane2 Unicode (extension B) */ ), "sun-extb" => array( 'R' => "Sun-ExtB.ttf", ), "unbatang" => array( /* Korean */ 'R' => "UnBatang_0613.ttf", ),
こんな感じです。今回は明朝体だけですがゴシック体を置き換えたいときはSun-ExtB.ttf というところを IPAからダウンロードしたゴシック体フォントに置き換えます。
この状態で再度プログラムを実行すると、
このように、おかしかった文字もちゃんと表示されるようになりました(^^)/
コメント