Posted at

Vue.js で日本語の PDF を生成する


環境

Vue: 2.5.17


日本語を使わない場合のミニマム実装

日本語を使わなくて良いなら、以下のような感じで速攻で作れる。

https://jsfiddle.net/eywraw8t/480739/

<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.39/pdfmake.min.js"></script>

<script src="https://cdnjs.cloudflare.com/ajax/libs/pdfmake/0.1.39/vfs_fonts.js"></script>

上記では便宜上、CDN から呼び出しているが、日本語を使わないなら普通に npm でインストールでも大丈夫。

pdfmake の公式サイトで、ブラウザ上からPDFの編集イメージが見られるのでオススメ。

http://pdfmake.org/playground.html


日本語を使いたい場合

まず、日本語を使用したい場合は以下に注意する必要がある。


  • vfs_fonts.js を少しいじる必要がある


    • そのため npm 非推奨



  • pdfmake の playground では日本語が文字化けるのであまり役に立たない

  • 後述の手順を踏めば日本語が使えるようにはなるが、一部使用できない文字がある( など)


完成イメージ


日本語を使用するまでの手順


ライブラリを導入する



  • pdfmake をダウンロードする

  • 日本語対応済みの vfs_fonts.js をダウンロードする


    • 自分で公式からフォークして作成しても良いが結構大変そうなので、先駆者のもの使用させてもらう




ライブラリを読み込む

Vue のコンポーネントでは <script> タグが使えないので、以下のように生成することで実現できる。

created() {

let pdfmakeScript = document.createElement("script");
pdfmakeScript.src = `/pdfmake/pdfmake.min.js`;
document.body.appendChild(pdfmakeScript);

let fontsScript = document.createElement("script");
fontsScript.src = `/pdfmake/vfs_fonts.js`;
document.body.appendChild(fontsScript);
}

しかし、pdfmake.min.js の後に vfs_fonts.js を読み込まなければいけないようで、上記だとたまにエラーになる。

参考になった issue

解決策として、index.html に以下のようにフルパスで定義すれば回避できる。

<script src="https://your-domain.jp/pdfmake/pdfmake.min.js"></script>

<script src="https://your-domain.jp/pdfmake/vfs_fonts.js"></script>

上記を実施する場合、ビルドされる場所にライブラリを格納する必要がある。


  • ビルド前のパス例

/public/pdfmake/pdfmake.min.js

/public/pdfmake/vfs_fonts.js


  • ビルド後のパス例

/dist/pdfmake/pdfmake.min.js

/dist/pdfmake/vfs_fonts.js


PDF を生成する

あとは設定した日本語のフォントを設定するだけで、日本語の PDF が生成できる。

methods: {

submit() {
pdfMake.fonts = {
// 日本語が使用可能なフォントを設定
GenShin: {
normal: "GenShinGothic-Normal-Sub.ttf",
bold: "GenShinGothic-Normal-Sub.ttf",
italics: "GenShinGothic-Normal-Sub.ttf",
bolditalics: "GenShinGothic-Normal-Sub.ttf"
}
};
const defaultStyle = "GenShin";
const docDefinition = {
content: [
{
text: "ヘッダー",
style: "header"
},
{
text: "サブヘッダー",
style: "subHeader"
},
{
text: "文章",
style: "sentence"
},
],
styles: {
header: {
fontSize: 35,
alignment: "center",
margin: [0, 0, 0, 50]
},
subHeader: {
fontSize: 20,
alignment: "left",
margin: [0, 0, 0, 10]
},
sentence: {
fontSize: 15,
alignment: "center",
margin: [0, 0, 0, 30]
},
},
};
pdfMake.createPdf(docDefinition).download();
}
}


あとがき

これでなんとか日本語のPDFを生成できた。

PDF の文字量が多くなってくるとかなり苦行なので、不変な部分は画像にして読み込んだ方が効率的だと思う。

せめて公式の playground が日本語対応してくれれば。。