#javascript で作る html から PDF 変換 pdfmake の日本語対応

pdfmake はブラウザー側で pdf 作成可能な javascript ライブラリです。デフォルトでは日本語未対応ですが、フォントを導入すると日本語文字化けなしできれいに作れます。
ブラウザー側に javascript だけで PDF 作成するときのメモまとめました。

#日本語対応:無料フォント IPA フォント使う

無料のフォントを探していたが、一部漢字対応しているけど、全角記号対応してないフォントもありましたが、最終的に IPA フォントにしました。

IPA フォントは 情報処理推進機構 IPA が作った仕様複製配布フリーの無料フォントです。

パック詳細:IPA フォント(IPA フォント 4 書体パック) IPAfont00303.zip

  • はじめにお読みください Readme_IPAfont00303.txt
  • IPA フォントライセンス v1.0 IPA_Font_License_Agreement_v1.0.txt
  • IPA ゴシック ipag.ttf
  • IPA P ゴシック ipagp.ttf
  • IPA 明朝 ipam.ttf
  • IPA P 明朝 ipamp.ttf

ダウンロード
IPA フォント(IPA フォント 4 書体パック)(opens new window)

その他の IPA フォント

IPA フォントはいずれIPA フォントライセンス v1.0(opens new window)のライセンスになります。

#pdfmake の初期設定

github からレポジトリダウンロードして使うことも可能
ダウンロード(opens new window)

#npm からインストールする場合

# package install
npm i pdfmake

mkdir -p node_modules/pdfmake/examples/fonts

# node_modules/pdfmake/examples/fontsディレクトリにフォント貼り付ける
#

# pdfmake作業ディレクトリにてビルド
cd node_modules/pdfmake && npm i && npm run build

#javascript 出来上がり

必要なパッケージ読み込んで、content いじって、吐き出す流れになります。
細かい設定は style や margin で調整

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
import htmlToPdfmake from "html-to-pdfmake";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
pdfMake.fonts = {
  ipa: {
    normal: "ipagp.ttf",
    bold: "ipagp.ttf"
  }
};

const content = [
  {
    table: {
      headerRows: 1,
      widths: ["*", "auto", 100],
      body: [
        ["日本語対応", "pdf印刷ダウンロード", "pdfmake"],
        ["Value 1", "Value 2", "Value 3",
        [{ text: "Bold value", bold: true }, "Val 2", "Val 3"]
      ]
    }
  }
];

const docDef = {
  defaultStyle: {
    font: "japaneseFont"
  },
  styles: {
    alignRight: {
      alignment: "right"
    },
    alignCenter: {
      alignment: "center"
    },
    bold: {
      fontSize: 24,
      bold: true
    }
  },
  content: content
};

pdfMake.createPdf(docDef).download('htmlPdfConvert.pdf');

#使用可能な属性プロパティ Property

#スタイル系 Style

項目その他
fontString
fontSizeNumber
lineHeightInt
boldBoolean
italicsBoolean斜体
alignmentStringleftcenterrightjustify
colorString
backgroundString
markerColorString
decorationStringunderlinelineThroughoverline
decorationStyleStringdasheddotteddoublewavy
decorationColorString)
var docDefinition = {
  content: [
    "This is a standard paragraph, using default style",
    { text: "This paragraph will have a bigger font", fontSize: 15 },
    {
      text: [
        "This paragraph is defined as an array of elements to make it possible to ",
        { text: "restyle part of it and make it bigger ", fontSize: 15 },
        "than the rest."
      ]
    }
  ]
};

#マージン Margin

margin:[左,上,右,下]
margin:[左右,上下]
margin: 左右上下

// margin: [left, top, right, bottom]
{ text: 'sample', margin: [ 5, 2, 10, 20 ] },

// margin: [horizontal, vertical]
{ text: 'another text', margin: [5, 2] },

// margin: equalLeftTopRightBottom
{ text: 'last one', margin: 5 }

#カラム Columns

2分等表示3分等表示段落分等表示する際に使えます。

{
  content: [
    {
      columns: [{ text: "ログインID " }, { text: "パスワード " }]
    }
  ];
}

#テーブル Table

テーブルはちょっとした癖がありますが、なれたら使いやすくなってます。

{
  content: [
    {
      columns: [{ text: "ログインID " }, { text: "パスワード " }]
    },
    {
      table: {
        widths: ["*", "auto", 100, "*"],
        body: [
          ["First", "Second", "Third", "The last one"],
          ["Value 1", "Value 2", "Value 3", "Value 4"],
          [{ text: "Bold value", bold: true }, "Val 2", "Val 3", "Val 4"]
        ]
      }
    },
    {
      table: {
        body: [
          [{ text: "First", width: 100 }, "Second", "Third", "The last one"],
          ["Value 1", "Value 2", "Value 3", "Value 4"],
          [
            { text: "Val 1", margin: 5 },
            { text: 1000, alignment: "right", bold: true },
            "Val 3",
            "Val 4"
          ]
        ]
      }
    }
  ];
}

#リスト List

HTML タグのulolみたいにリスト作成

{
  ul: ["list1", "list2", { text: "list3", bold: true }];
},
{
  ol: ["olist1","olist2","olist3"]
}

#画像 Image SVG

HTML タグのimgみたいなもの、ブラウザーなら base64 エンコードデータにする必要があります。

{
  image: 'data:image/jpeg;base64,...encodedContent...',
  width: 150,
  height: 150
},
{
  svg: '<svg width="300" height="200" viewBox="0 0 300 200">...</svg>'
}

HTML のaタグみたいなもの

{text: 'google', link: 'http://google.com'},
{text: 'Go to page 2', linkToPage: 2}

#QR コード

シンプルに一行だけで QR コード作れます。

{
  content: [
    // basic usage
    { qr: "text in QR" },

    // colored QR
    { qr: "text in QR", foreground: "red", background: "yellow" },

    // resized QR
    { qr: "text in QR", fit: "500" }
  ];
}

オプション & プロパティ

項目必須備考
qr必須text in QR code
foregroundoptional
backgroundoptional
fitoptional
versionoptional
eccLeveloptional可能値:LMQHデフォルトL
modeoptional可能値:numericalphanumericoctet
maskoptional

#HTML から変換してくれるツール htmlToPdfmake

pdfmake 詳しく学習しなくても html で変換してくれるツールがあります。

import pdfMake from "pdfmake/build/pdfmake";
import pdfFonts from "pdfmake/build/vfs_fonts";
import htmlToPdfmake from "html-to-pdfmake";
pdfMake.vfs = pdfFonts.pdfMake.vfs;
pdfMake.fonts = {
  ipa: {
    normal: "ipagp.ttf",
    bold: "ipagp.ttf"
  }
};

export function hcloMember|| {
  const html = `
    <div>
      <h1 style="color: red;">日本語</h1>
      <table style="width: 100%; font-size: 10px">
        <tr>
          <th>お客様ID</th>
          <td>0000</td>
        </tr>
        <tr>
          <th>契約者名</th><td>テスト太郎</td>
        </tr>
        <tr>
          <th>契約者住所</th><td>大阪府大阪市2-2-3 本末ビル2F</td>
        </tr>
      </table>
    </div>`;
  const docDef = {
    content: [htmlToPdfmake(html)],
    defaultStyle: {
      font: "ipa"
    }
  };

  pdfMake.createPdf(docDef).download('htmlPdfConvert.pdf');
}

pdfmake Document(opens new window)
pdfmake Playground(opens new window)

#Uncaught (in promise) File 'ipagp.ttf' not found in virtual file system

Uncaught (in promise) File 'ipagp.ttf' not found in virtual file system

エラーメッセージが出ったipagp.ttfファイルがないことが原因で、gulp でフォント再ビルドする必要があります。
vfs は virtual file system の略かなあ?

pdfmake/build/vfs_fonts.js 設定して上げれば問題解決

# gulp使うので、gulpインストール
npm i -g gulp

# cd node_modules/pdfmakeディレクトリまで移動
cd node_modules/pdfmake/

# フォント格納するためのディレクトリ作成
mkdir examples && mkdir examples/fonts

# フォントコピー 貼り付け
cp ../../public/fonts/*.ttf examples/fonts/

# npm インストール実行
npm install

# ガルプでフォント作成 vfs_fonts 更新
gulp buildFonts

# できました!
[16:04:31] Using gulpfile ~/www.example.info/node_modules/pdfmake/gulpfile.js
[16:04:31] Starting 'buildFonts'...
[16:06:00] Finished 'buildFonts' after 1.47 min
2019-12-19
  • javascript

関連記事

javascript 日本語 shift-js 対応 CSV ダウンロード
ブラウザーで動く javascript のクッキー操作ライブラリ js-cookie
ReferenceError: location is not defined
nodejs 使う時のエラーたち
javascript reduce 連想配列の合計計算覚えよう
vuejs i18n の html-lang と font 設定
正規表現一覧 よく使う検索・置換のパターン
開発時によく使うゼロ埋めパディング作業まとめ
javascript 面接問題のいろいろ
Javascript vuejs の validation 正規表現でフォームチェック作ったときのメモ
nuxtjs と codeigniter で jwt システム構築
javascript 楽しく遊ぼう!メッセージつぶやくウシ cowsay