developer's diary

最近はc#のエントリが多いです

pdf-lib.jsというライブラリを利用すると、日本語フォントを埋め込んだPDFをブラウザ上で生成できる

2014年にjsPDFとかFileSaver.jsとか使って、ブラウザでPDF出力みたいなことしてたんですが、 その時は、日本語フォントの埋め込みができなかったので、canvasに日本語の文字書いて無理くりimageをPDFに出力するということをやってました。

で、6年たった今どれくらい技術は発達してるのか?と思い。 調べてみました。

あるじゃないですか。フォント埋め込みできるjsのpdf生成ライブラリ

pdf-lib.js

pdf-lib.js.org

サンプルソース

    const { PDFDocument, rgb } = PDFLib

    // ボタン押下時の処理
    async function createPdf() {
      // PDFドキュメント生成
      const pdfDoc = await PDFDocument.create();
      // フォント埋込のおまじない
      pdfDoc.registerFontkit(fontkit);
      //読み込みフォントのURL
      const url = './font/DotGothic16-Regular.ttf';
      //フォントを読み込んでバイト配列で保持
      const fontBytes = await fetch(url).then((res) => res.arrayBuffer());
      //フォント埋め込み
      const font = await pdfDoc.embedFont(fontBytes);
      //PDFに1ページ追加
      const page = pdfDoc.addPage();
      //印字
      page.drawText('勇者は頑張ってjavascriptでpdfを印刷し...',{x: 0,y: 800, size: 30,font: font,color: rgb(0,0,0)});
      page.drawText('勇者は頑張ってjavascriptでpdfを印刷し...',{x: 0,y: 770, size: 20,font: font,color: rgb(0,0,0)});
      page.drawText('勇者は頑張ってjavascriptでpdfを印刷し...',{x: 0,y: 750, size: 10,font: font,color: rgb(0,0,0)});
      page.drawText('勇者は頑張ってjavascriptでpdfを印刷し...',{x: 0,y: 740, size: 8,font: font,color: rgb(0,0,0)});
      //PDFのバイト配列取得
      const pdfBytes = await pdfDoc.save();
      //バイト配列をダウンロードさせる
      download(pdfBytes, "勇者は.pdf", "application/pdf");
    }

サンプル

mitsugeek.github.io

PDFのサイズは?

フォント自体のサイズは、4.12 MBなんですが、生成されたPDF自体は、1.75 MBでした。

ちなみに、ipag.ttfでやってみると、フォントのサイズが5.94 MBで、生成された4.13 MBとなりました。

感想

ファイルサイズが大きい印象です。

Laravel-dompdfだと、画像含んでも1MByteいかないので、埋め込みフォントのところがボトルネックになるのかな。

ただ、サーバレスでPDFが生成できるのは、メリットが大きいですね。