qtatsuの週報

初心者ですわぁ

jsPDFをscriptタグで配置する手順&日本語フォントを使う2種類の方法まとめ

前書き

jsPDFを、npmなどを使わずGitHubから直接ダウンロードし、scriptタグを使って読み込む方法をまとめます(プロジェクトの制約上この方法となりました)。

またjsPDFはそのままだと日本語を使うことができません。日本語フォントを読み込む方法を、公式ドキュメントにも書かれている2種類の方法でやってみます。

また、実行環境はMacOS Catalina 10.15.6で、Djangoを使ってtemplateを作成しています。 (htmlにDjangoのテンプレートタグを用いています。{% static 'xxx' %} ←こういうやつです。)

jQueryとjsPDFのソースファイルをダウンロードする

jQuery

Download jQuery | jQuery

Download the compressed, production jQuery 3.5.1 を右クリックして、別名で保存→プロジェクト配下に保存しました。

jsPDF

https://github.com/MrRio/jsPDF

上記GitHubのページの右の方に、Releasesの項目があります。そこを開くと

Releases · MrRio/jsPDF · GitHub

こちらになります。「Source Code (zip)」とあるので、それをダウンロードします。

利用するのはjsPDF-2.0.0/dist/jspdf.umd.jsです。これを先ほどのjqueryファイルと同じく、プロジェクト配下にコピーします。

umdファイルはscriptタグで読み込みをするための形式とのことです。公式ドキュメントの以下の部分に書いてありました。

Home - Documentation

jspdf.umd.*.js: UMD module format. For AMD or script-tag loading.

htmlテンプレートを作成し、以下のjsを実行してみます。

注意点: 公式ドキュメントではvar doc = new jsPDF();としていますが、scriptタグで直接読んでいるため、jsPDFは直にインポートされておらず、jspdf.jsPDFというnamespaceにある様です。

jQuery(function($){
    const doc = new jspdf.jsPDF(); // 注意!jspdf配下から呼ぶ。
    doc.text('Hello,世界!', 10, 10);
    doc.save('test.pdf');
});

f:id:Qtatsu:20200815195344p:plain
日本語が文字化け
うまくいってますが、日本語だけ文字化けしています

フォントの確認と指定方法

jspdfを読み込んでいるhtmlファイルをブラウザで開き、ブラウザのdeveloperツールを開きます。 chrome/macos環境なら、option + command + i で開きます。

Consoleタブを開き、以下の様にしてフォント一覧を確認します。使うのは、以下の公式ドキュメントリンクにあるgetFontListメソッドです。

jsPDF - Documentation

const jspdfObject = jspdf.jsPDF();
jspdfObject.getFontList();

f:id:Qtatsu:20200815195329p:plain
フォント一覧

上記の出力結果を参照し、パラメータをセットします。Keyがフォント名、valueとなっているlistが設定可能なスタイルです。 フォントの指定は、以下の様にsetFontメソッドによって行います。

jsPDF - Documentation

jQuery(function($){
    const doc = new jspdf.jsPDF();
    doc.setFont('Helvetica', 'Bold');  // フォントを適応
    doc.text('Hello,世界!', 10, 10);
    doc.save('test.pdf');
});

f:id:Qtatsu:20200815195310p:plain
Helvetica(Bold)適応成功

文字化けはしていますが(Helveticaは日本語を扱えないフォントなので)、フォントが適応されていることがわかります。

日本語フォントmplusの追加

Home - Documentation

こちらのUse of Unicode Characters / UTF-8:という項目に従い、2種類の方法を試します。

mplusのダウンロード

自分がやってみたところ、jsPDFは日本語フォントに関して、受け付けないものもある様でした。(Myricaはダメでした) mplusは有効な日本語フォントでしたので、そちらを使って解説します。

M+ FONTS | JAPANESE

上のサイトからダウンロードします。指示に従い、mplus-TESTFLIGHT-063a.tar.xzをダウンロードしてその辺で解凍しておきます。(ttfファイルがたくさん出てくればOKです).

日本語フォントの設定方法1. 公式のファイル変換ツールを使う(多分推奨)

公式の変換ツール

先述の公式ドキュメントから、フォントのttfファイルをjsファイルに変換するツールのリンクが示されていました。これを使うと、通常のjsファイルと同じ様に読み込んで使うことができるようにフォントのttfファイルを変換してもらえる様です。

先ほどダウンロードしたmplusの、mplus-TESTFLIGHT-63a/mplus-1p-black.ttfを選択してアップロードします。fontNameはmplus-1p-blackと自動的に入るはずです。fontStyleはnormalを選択してください。

また、moduleFormatはUMDを選択してください。そうすることで、scriptタグで読み込み可能となる様です。

あとは変換後のファイル(mplus-1p-black-normal.js)をダウンロードし、jsPDFを利用している自分のjsファイルと同じディレクトリに置きます。

Djangoの場合、以下の様にしてhtmlファイルに読み込みます。

  <body>
    <h1>test pdf</h1>
    <script src="{% static 'js/jquery-3.5.1.min.js' %}"></script>
    <script src="{% static 'js/jspdf.umd.min.js' %}"></script>
    <script src="{% static 'js/mplus-1p-black-normal.js' %}"></script>
    <script src="{% static 'js/test.js' %}"></script>
  </body>

追記 mplusのjsでjspdfが見つからないという旨のエラーが出るときは、 type="module"を付加します。

<script type="module" src="{% static 'js/mplus-1p-black-normal.js' %}"></script>

ここで、先ほど述べた様にフォント一覧をDeveloperツールのコンソールから確認します。

f:id:Qtatsu:20200815195242p:plain
mplusが追加されていることを確認

mplusが追加されているのがわかります。

では、以下の様にtest.jsを書き直します。

jQuery(function($){
    const doc = new jspdf.jsPDF();
    doc.setFont('mplus-1p-black', 'normal');
    doc.text('Hello,世界!', 10, 10);
    doc.save('test.pdf');
});

f:id:Qtatsu:20200815195205p:plain
日本語出力に成功

元気よく、世界にご挨拶できました。

日本語フォントの設定方法2. base64形式にしたフォントのttfを直接設定する。

先述の公式ドキュメントに、第二の方法として述べられていた方法です。

また、以下のサイトを参考にさせていただきました。

JavaScriptでjsPDFを使ってPDFファイルを生成する(日本語対応)

const doc = new jsPDF();

const myFont = // ここにBase64エンコードしたstringをおく.

doc.addFileToVFS("mplus.ttf", myFont);
doc.addFont("mplus.ttf", "mplus", "normal");

上述のBase64エンコードは、以下の様に行います(base64コマンド)

$ base64 --input=mplus-TESTFLIGHT-063a/mplus-1p-black.ttf --output=mplus.txt

これで出力された結果を上述のmyFont変数で束縛すればいいんですが、自分がエディタで直接ペーストしようとするとPCが固まってしまって無理でした...base64に変換した文字列が長すぎるようです。 なので、一旦別のファイルで変数myFontに束縛し、それをインポートする様にしました。 以下がその手順です。

$ echo "export const myFont = \`" >> cms/static/js/mplus.js

# 先ほどの、base64化したファイル。
$ cat mplus.txt >> cms/static/js/mplus.js
$ echo "\`;" >> cms/static/js/mplus.js
export const myFont = `base64の文字列~`;

こんなイメージになります。

それでは、フォントを設定していきます。

import {myFont} from './mplus.js';

jQuery(function($){
    const doc = new jspdf.jsPDF();
    doc.addFileToVFS('mplus.ttf', myFont);
    doc.addFont('mplus.ttf', 'mplus', 'normal');
    doc.setFont('mplus', 'normal');  // ↑で名付けた名前を設定する。
    doc.text('Hello,世界!', 10, 10);
    doc.save('test.pdf');
});

このままでは動きません。mplus.jsをインポートできないからです。 インポートするには、type=module 属性を呼び元のjs(test.js)に付与すればOKです。

<script type='module' src="{% static 'js/test.js' %}"></script>

日本語をPDF出力できれば成功です。