JavaScriptでjsPDFを使ってPDFファイルを生成する(日本語対応)
今までWebページ上でPDFファイルを作る必要があった場合には大抵PHPで処理してきましたが、ふとJavaScriptでPDFの作成が出来ないものかと思い、ちょっと調べてみました。
jsPDFというライブラリがあった
まさにそのものズバリなのですが、JavaScriptでPDFを作成するためのライブラリが公開されていました。
https://github.com/MrRio/jsPDF
jsPDFの使い方
jsPDFの使い方は至って簡単で、こんな感じ。
<html>
<head>
<script src='/js/jspdf.min.js' type='text/javascript'></script>
</head>
<body>
<script>
var doc = new jsPDF();
doc.text('Hello World', 10, 10);
doc.save('test.pdf');
</script>
</body>
</html>
動作サンプル
ボタンを押すとPDFファイルがダウンロードできます。
解説
jspdf.min.jsを読み込み、new jsPDF();でクラスを生成し、textメソッドで文字を書き込み、saveメソッドでPDFをダウロードする、と非常にシンプルでわかりやすいライブラリです。
(ちなみにtextメソッドの後ろに指定している10,10はX座標とY座標)
ただ………ありがちな話ですが、デフォルトだと日本語対応してないんですよね。
jsPDFでは日本語フォントが指定できない
doc.text('Hello World テスト', 10, 10);というように日本語を入れると、下記のように日本語部分のみ文字化けします。
jsPDFにはaddFontやsetFontといった関数も用意されているため、MeiryoとかIPAExMinchoとか指定してやれば動くのでは、と試行錯誤してみましたが、どうにもうまくいきません。
jsPDFでカスタムフォントを読み込ませて日本語を表示する
サンプルコード
//base64エンコードしたフォントを読み込ませる
var base64_font = 'AAEAAAAUAQAABABAQkFTRYWPk+(長いので省略)';
doc.addFileToVFS("test.ttf", base64_font);
doc.addFont('test.ttf', 'test', 'normal');
doc.setFont('test', 'normal');
//日本語入りのテキストを書く
doc.text('Hello World テスト', 10, 10);
doc.save('test.pdf');
動作結果
解説
まぁ… 結果だけ見ると解決してるんですけど、サンプルコードの「長いので省略」と書かれているところが問題でして。
フォントファイルをbase64エンコードして読み込ませるのは良いのですが、フォントってデカいじゃないですか。具体的には今回の例ではIPAex明朝を使ったのですが、7MBほどありました。こいつをbase64エンコードすると10MBくらいになります。
10MBのページって…どうなのよ…。
JavaScriptでPDF作成をしたい人は他にもいるようで、検索してみると日本語を扱うためにアレコレ工夫している方がたくさんいらっしゃいますが、やはり最終的にはフォントを埋め込んでいるように見受けられます。
一応、あまり使わない文字を削った軽量化フォントを用意することで、2MBくらいまで小さくしている例もありましたが、それでもやっぱりデカいですよねぇ。
わざわざフォントを埋め込まなくても日本語フォント名の指定さえうまくできれば良いのだけれど、うーん。
PHPでフォントファイルをbase64エンコード
サンプルを掲載するまでもない気もしましたが念の為。
PHPでIPAex明朝のフォントファイルを読み込んでbase64エンコード化した ipaexm.txt を出力するサンプルです。
<?php
file_put_contents('ipaexm.txt', base64_encode(file_get_contents('ipaexm.ttf')));
?>
これで出力された10MBほどある ipaexm.txt をテキストエディターで開いて、var base64_font = 'ほにゃらら'; 部分にコピペして実装したわけです。
まとめ
- JavaScriptでPDFを作成するには jsPDF ライブラリを使うと簡単。
https://github.com/MrRio/jsPDF - 但し、そのままでは日本語に対応していないので、カスタムフォントとしてフォントデータを読み込む必要がある。
- 日本語フォントは10MBくらい(軽量化しても2MBくらい)あるため、実用的かと言われると微妙なところか
格安サーバーを使うことが多いため、PDF作成処理をJavaScriptで実装すればサーバーの負荷が減るかも、なんて考えで調べてみましたが、フォントファイルの読み込みだけで10MBの転送が毎回発生するようだと本末転倒ですね。
日本語を使う以上は従来どおりPHPでPDF生成したほうが良いかなぁ。