pdfmeとは?

pdfme は、Node.js やブラウザの JavaScript を使って 簡単にPDFを作成 できるライブラリです。開発者は Wix のアドボケイトである Kyoheiさん(@labelmake) です。

この記事では、pdfmeを使って 請求書(インボイス)を作成 する手順を解説します。

必要なライブラリ

pdfmeではimport文を使用するため、以下のライブラリを利用します。

  • vite(フロントエンド開発環境)
  • pdfme(PDF生成ライブラリ)

セットアップ手順

まずvite環境を構築します。

npm create vite@latest pdfme-invoice-generator -- --template react
cd pdfme-invoice-generator

作成したプロジェクトにpdfmeをインストールします。

npm install @pdfme/generator @pdfme/common @pdfme/schemas

これで環境の準備は完了です。

帳票テンプレートについて

pdfmeでは、ブラウザ上でPDFのテンプレートを作成できます。多数のサンプルが用意されており、それらを参考にしながら自分の帳票を作成できます。

今回は請求書(インボイス)のテンプレートを利用して説明します。

このテンプレートは、以下のリンクからダウンロードできます。

https://pdfme.com/template-design

リンク先では、他のサンプルテンプレートも閲覧・編集できますので、ぜひ活用してください。

実装方法

1. 必要なライブラリのインポート

PDFを作成するために必要なライブラリをインポートします:

import { useEffect, useState } from "react"
import type { Template, Font } from "@pdfme/common"
import { text, barcodes, image } from "@pdfme/schemas";
import { generate } from "@pdfme/generator"

2. 生成に必要なデータの準備

const [template, setTemplate] = useState<Template | null>(null)
const [inputs, setInputs] = useState<Record<string, string>>({})

inputsはPDFに埋め込むデータで、以下のようなJSON形式です。各キーはテンプレートデザイナーで指定したものと一致させる必要があります:

{
  No: '100',
  Due: '2025-01-01',
  InvoiceTo: `〒113-0034
東京都文京区湯島二丁目31番14号 LUCID SQUARE YUSHIMA`,
  Company: `株式会社アシアル
TEL: 03-5875-6862
(受付時間:11:00~15:00)
FAX: 03-5875-6216
E-mail: info@asial.co.jp`,
  Description1: "商品アイテム 1",
  Price1: "5,000",
  Description2: "商品アイテム 2",
  Price2: "10,000",
  Description3: "商品アイテム 3",
  Price3: "15,000",
  Subtotal: "30,000",
  Tax: "2,400",
  TaxRate: "8",
  Total: "32,400",
}

3. テンプレートの読み込み

ファイル選択UIを使ってテンプレートJSONを読み込みます:

<input type="file" accept='application/json'
  onChange={async (event) => {
    const file = event.target.files?.item(0)
    if (!file) return
    const template = JSON.parse(await file.text()) as Template
    setTemplate(template)
  }}
/>

4. 帳票データの設定

帳票に埋め込む値をJSON形式で編集できるようにします:

<textarea
  value={JSON.stringify(inputs, null, 2)}
  onChange={(event) => {
    setInputs(JSON.parse(event.target.value))
  }}
/>

5. PDF生成ボタンの実装

<button onClick={generatePdf}>Generate PDF</button>

6. PDF生成関数の実装

PDF生成は以下のように行います。

  1. テンプレートが存在するか確認
  2. 使用するプラグインを指定(テキスト、QRコード、画像など)
  3. テンプレートと入力データを元にPDFを生成
  4. 生成したPDFデータをBlobに変換
  5. BlobからURLを作成
  6. 新しいタブでPDFを表示
const generatePdf = async () => {
  if (!template) return
  const plugins = {
    Text: text,
    'QR Code': barcodes.qrcode,
    Image: image,
  };    
  const pdf = await generate({ template, inputs: [inputs], plugins });
  const blob = new Blob([pdf], { type: 'application/pdf' })
  const url = URL.createObjectURL(blob)
  window.open(url)
}

日本語対応方法

デフォルトでは日本語フォントが用意されていないため、日本語を表示するには追加の設定が必要です。

  1. 日本語フォント(例:NotoSansJP-Regular.woff)を用意し、public フォルダに保存します。
    日本語フォントは、Google Fonts の公式サイトから取得できます。
  2. Noto Sans JP フォントをダウンロードリンクからフォントファイルをダウンロードします。
  3. フォント設定を定義します:
const font: Font = {
  NotoSansJP: {
    data: "http://localhost:5173/NotoSansJP-Regular.woff",
    fallback: true,  // フォントが見つからない場合のデフォルトに設定
  },
};

また、PDF生成時にフォント設定をオプションとして指定します。

const pdf = await generate({ 
  template, 
  inputs: [inputs], 
  plugins, 
  options: { font } 
});

これにより、日本語も正しく表示されるPDFが生成されます。

まとめ

pdfmeを使ったPDF生成の利点は、次のものがあります。

  • サーバーサイドに頼らずにブラウザ上でPDFを生成できる
  • ユーザーが指定した内容(見積もり情報など)をその場でPDFに変換できる
  • オフラインでも生成可能(フォント情報は別途考慮が必要)
  • 直感的なテンプレートエディタで作成・編集が容易

このライブラリを活用することで、自社サービスやアプリに簡単にPDF生成機能を組み込むことができます。

詳細は公式サイト pdfme をご覧ください。