# 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 フォント

# 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

項目 その他
font String
fontSize Number
lineHeight Int
bold Boolean
italics Boolean 斜体
alignment String left center right justify
color String
background String
markerColor String
decoration String underline lineThrough overline
decorationStyle String dashed dotted double wavy
decorationColor String )
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 タグのul olみたいにリスト作成

{
  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
foreground optional
background optional
fit optional
version optional
eccLevel optional 可能値: L M Q H デフォルト L
mode optional 可能値: numeric alphanumeric octet
mask optional

# 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 非同期処理 async と await のメモ
Nuxt.js と Ant Design Vue 2 テーマカスタマイズ
JavaScript ライブラリ aos.js 使ってスクロール連動アニメーション
Cookie localStorage sessionStorage の違い
大きいファイルをスライス分割してアップロード
Javascript DataTables で excel 風 table 作る
javascript 配列 重複排除
bootstrap vuejs 使って generate する際に babel が icons ファイル max 500KB エラー
開発時によく使うゼロ埋めパディング作業まとめ
nuxtjs と codeigniter で jwt システム構築
javascript 日本語 shift-js 対応 CSV ダウンロード
開発におけるコーディングルール・規約
javascript  指定場所にスムーズにスクロールする方法
react 強制的にレンダリングする方法
Jsconfig と Tsconfig
Javascript var let const 変数宣言の違い
Javascript 電話番号フォーマット
国際化 i18n と地域化 L10N
javascript 文字列と配列検索 indexOf findIndex find some includes 関数の違い
vuejs back to top button component 作成
Nuxtjs 動的なルーティング静的ページ自動生成
キーコード取得 & キーコード一覧
Sweet Alert swal に複数 content
moment.js 使って日本語曜日対応
javascript 開発で出会った TypeError
ReferenceError: location is not defined
vuejs で omisejapan の決済フォーム作成した時のメモ
ブラウザーで動く javascript のクッキー操作ライブラリ js-cookie
javascript reduce 連想配列の合計計算覚えよう
nodejs 使う時のエラーたち
javascript 楽しく遊ぼう!メッセージつぶやくウシ cowsay
Javascript vuejs の validation 正規表現でフォームチェック作ったときのメモ
正規表現一覧 よく使う検索・置換のパターン
javascript password generator ランダム文字列パスワード作成