2026/05/12

請求書PDFテンプレートのHTMLデザインガイド|CSS・レイアウト・日本語対応

請求書HTMLテンプレートPDF生成CSSデザイン

請求書PDFの自動生成でAPIの呼び出し方を理解したら、次のステップはテンプレートのデザイン品質を上げることです。この記事では、PDF APIで使うHTMLテンプレートの設計パターンを、CSSレイアウト・日本語対応・インボイス制度対応まで実装コード付きで解説します。

テンプレート設計の基本方針

請求書テンプレートを設計するとき、以下の3点を最初に決めます。

  1. ページサイズ: A4縦(最も一般的)
  2. 用紙の余白: 天地20mm / 左右15mm が標準
  3. フォント: 日本語対応の游ゴシック系またはNoto Sans JP

@page ルールでページ設定を固定する

@page {
  size: A4 portrait;
  margin: 20mm 15mm;
}

body {
  font-family: 'Noto Sans JP', 'Hiragino Kaku Gothic ProN', sans-serif;
  font-size: 10pt;
  line-height: 1.6;
  color: #1a1a1a;
  margin: 0;
}

CSS @page ルールの詳細は CSS @page ルール PDFガイドを参照してください。

ヘッダーセクション:会社情報と請求書番号

<header class="invoice-header">
  <div class="company-info">
    <h1 class="company-name">株式会社サンプル</h1>
    <p>〒100-0001 東京都千代田区千代田1-1-1</p>
    <p>TEL: 03-0000-0000 FAX: 03-0000-0001</p>
    <p>登録番号: T1234567890123</p>
  </div>
  <div class="invoice-meta">
    <h2 class="invoice-title">請求書</h2>
    <table class="meta-table">
      <tr><th>請求書番号</th><td>INV-2026-0042</td></tr>
      <tr><th>発行日</th><td>2026年5月12日</td></tr>
      <tr><th>お支払期限</th><td>2026年6月30日</td></tr>
    </table>
  </div>
</header>
.invoice-header {
  display: flex;
  justify-content: space-between;
  align-items: flex-start;
  border-bottom: 2px solid #0052cc;
  padding-bottom: 12pt;
  margin-bottom: 16pt;
}

.company-name {
  font-size: 14pt;
  font-weight: 700;
  color: #0052cc;
  margin: 0 0 4pt;
}

.invoice-title {
  font-size: 22pt;
  font-weight: 700;
  color: #0052cc;
  margin: 0 0 8pt;
  text-align: right;
}

.meta-table {
  margin-left: auto;
  border-collapse: collapse;
  font-size: 9pt;
}

.meta-table th {
  text-align: right;
  padding: 2pt 8pt 2pt 0;
  color: #555;
  font-weight: normal;
}

.meta-table td {
  text-align: left;
  font-weight: 600;
}

宛先セクション:請求先の表示

<section class="bill-to">
  <p class="bill-to-label">請求先</p>
  <p class="company-name-large">{{client_name}} 御中</p>
  <p>{{client_address}}</p>
  <p>ご担当者: {{contact_name}} 様</p>
</section>
.bill-to {
  background: #f5f7fa;
  border-left: 4px solid #0052cc;
  padding: 10pt 12pt;
  margin-bottom: 20pt;
}

.bill-to-label {
  font-size: 8pt;
  color: #777;
  margin: 0 0 4pt;
  text-transform: uppercase;
  letter-spacing: 0.05em;
}

.company-name-large {
  font-size: 14pt;
  font-weight: 700;
  margin: 0 0 4pt;
}

明細テーブル:請求項目の設計

請求書の核心は明細テーブルです。行が多くなっても読みやすい縞模様と、金額の右揃えを実装します。

<table class="line-items">
  <thead>
    <tr>
      <th class="col-no">No</th>
      <th class="col-desc">品目・摘要</th>
      <th class="col-qty">数量</th>
      <th class="col-unit">単位</th>
      <th class="col-price">単価</th>
      <th class="col-amount">金額</th>
      <th class="col-tax">税率</th>
    </tr>
  </thead>
  <tbody>
    {{#each items}}
    <tr>
      <td class="col-no">{{@index_plus_1}}</td>
      <td class="col-desc">{{description}}</td>
      <td class="col-qty text-right">{{quantity}}</td>
      <td class="col-unit text-center">{{unit}}</td>
      <td class="col-price text-right">{{unit_price_formatted}}</td>
      <td class="col-amount text-right">{{amount_formatted}}</td>
      <td class="col-tax text-center">{{tax_rate}}%</td>
    </tr>
    {{/each}}
  </tbody>
</table>
.line-items {
  width: 100%;
  border-collapse: collapse;
  margin-bottom: 16pt;
  font-size: 9pt;
}

.line-items thead tr {
  background-color: #0052cc;
  color: #ffffff;
}

.line-items thead th {
  padding: 6pt 8pt;
  text-align: center;
  font-weight: 600;
}

.line-items tbody tr:nth-child(even) {
  background-color: #f0f4ff;
}

.line-items tbody td {
  padding: 5pt 8pt;
  border-bottom: 1px solid #e0e7ff;
  vertical-align: middle;
}

/* 列幅の固定 */
.col-no    { width: 5%; }
.col-desc  { width: 38%; }
.col-qty   { width: 7%; }
.col-unit  { width: 7%; }
.col-price { width: 14%; }
.col-amount{ width: 15%; }
.col-tax   { width: 7%; }

.text-right  { text-align: right; }
.text-center { text-align: center; }

HTMLテーブルのPDF出力における詳しいCSSテクニックはHTML to PDF テーブルレイアウトガイドも参照してください。

合計金額セクション:税率別の集計

インボイス制度(適格請求書等保存方式)では、税率ごとの消費税額を明記する必要があります。

<div class="totals-wrapper">
  <div class="tax-summary">
    <h3>消費税内訳</h3>
    <table class="tax-table">
      <thead>
        <tr><th>税率</th><th>対象金額</th><th>消費税額</th></tr>
      </thead>
      <tbody>
        <tr>
          <td>10%対象</td>
          <td class="text-right">{{tax10_base_formatted}}</td>
          <td class="text-right">{{tax10_amount_formatted}}</td>
        </tr>
        <tr>
          <td>8%対象(軽減税率)</td>
          <td class="text-right">{{tax8_base_formatted}}</td>
          <td class="text-right">{{tax8_amount_formatted}}</td>
        </tr>
      </tbody>
    </table>
  </div>
  <div class="grand-total">
    <table class="total-table">
      <tr>
        <th>小計</th>
        <td class="amount">{{subtotal_formatted}}</td>
      </tr>
      <tr>
        <th>消費税合計</th>
        <td class="amount">{{tax_total_formatted}}</td>
      </tr>
      <tr class="grand-total-row">
        <th>合計金額(税込)</th>
        <td class="amount total">{{grand_total_formatted}}</td>
      </tr>
    </table>
  </div>
</div>
.totals-wrapper {
  display: flex;
  justify-content: flex-end;
  gap: 20pt;
  margin-bottom: 20pt;
}

.tax-summary h3 {
  font-size: 9pt;
  color: #555;
  margin: 0 0 6pt;
}

.tax-table, .total-table {
  border-collapse: collapse;
  font-size: 9pt;
}

.tax-table th, .tax-table td,
.total-table th, .total-table td {
  padding: 4pt 10pt;
  border: 1px solid #ddd;
}

.total-table th {
  text-align: left;
  background: #f5f7fa;
  min-width: 110pt;
}

.total-table .amount {
  text-align: right;
  min-width: 80pt;
}

.grand-total-row th,
.grand-total-row td {
  background-color: #0052cc;
  color: #ffffff;
  font-size: 11pt;
  font-weight: 700;
}

.grand-total-row .amount.total {
  font-size: 13pt;
}

備考・振込先セクション

<section class="notes-section">
  <div class="payment-info">
    <h3>お振込先</h3>
    <p>○○銀行 ××支店 普通口座 1234567</p>
    <p>口座名義: カ)サンプル</p>
    <p class="note">振込手数料はご負担をお願いいたします。</p>
  </div>
  {{#if notes}}
  <div class="custom-notes">
    <h3>備考</h3>
    <p>{{notes}}</p>
  </div>
  {{/if}}
</section>
.notes-section {
  display: flex;
  gap: 20pt;
  font-size: 9pt;
  border-top: 1px solid #ddd;
  padding-top: 12pt;
}

.notes-section h3 {
  font-size: 9pt;
  font-weight: 700;
  margin: 0 0 6pt;
  color: #333;
}

.note {
  color: #888;
  font-size: 8pt;
}

複数ページ対応:ヘッダー・フッターの繰り返し

明細行が多い場合にページをまたぐ際、各ページに会社名やページ番号を表示します。

/* テーブルヘッダーを各ページの先頭に繰り返す */
.line-items thead {
  display: table-header-group;
}

/* ページフッター */
@page {
  @bottom-center {
    content: counter(page) " / " counter(pages);
    font-size: 8pt;
    color: #aaa;
  }
}

/* ページをまたぐ行の途中での分割を防ぐ */
.line-items tbody tr {
  page-break-inside: avoid;
}

日本語フォントの設定

PDF出力で日本語を正しく表示するには、フォントを明示的に指定します。

/* システムフォントのフォールバックチェーン */
body {
  font-family:
    'Noto Sans JP',
    'Hiragino Kaku Gothic ProN',
    'Hiragino Sans',
    'Yu Gothic Medium',
    'Meiryo',
    sans-serif;
}

/* 金額は等幅フォントで揃える */
.amount, .col-price, .col-amount {
  font-family: 'Noto Sans Mono', 'Courier New', monospace;
}

日本語フォントの詳細設定はHTML to PDF 日本語フォントガイドを参照してください。

APIへの送信

作成したHTMLテンプレートに動的データを注入して送信します。

const template = fs.readFileSync('invoice-template.html', 'utf-8');

async function generateInvoicePdf(invoiceData) {
  // テンプレート変数を置換(実際はHandlebarsやEJSを使うことを推奨)
  const html = template
    .replace('{{client_name}}', invoiceData.clientName)
    .replace('{{invoice_number}}', invoiceData.invoiceNumber);
    // ...

  const response = await fetch('https://pdf.funbrew.cloud/api/v1/pdf', {
    method: 'POST',
    headers: {
      'Authorization': `Bearer ${process.env.FUNBREW_PDF_API_KEY}`,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      html,
      filename: `invoice-${invoiceData.invoiceNumber}.pdf`,
      options: {
        format: 'A4',
        margin: { top: '20mm', bottom: '20mm', left: '15mm', right: '15mm' },
        print_background: true,
      },
      metadata: {
        invoice_number: invoiceData.invoiceNumber,
        customer_id: invoiceData.customerId,
      },
    }),
  });

  return response.json();
}

PlaygroundでHTMLを貼り付けてプレビューすれば、テンプレートの仕上がりをすぐ確認できます。

テンプレートデザインのチェックリスト

  • @page でA4サイズと余白を指定している
  • 日本語フォントのフォールバックを設定している
  • 金額列は右揃えにしている
  • theaddisplay: table-header-group を設定し、複数ページで繰り返している
  • 税率別内訳(10%・8%)を明記している(インボイス制度対応)
  • 登録番号(T + 13桁)を記載している(インボイス制度対応)
  • page-break-inside: avoid で行が途中で分割されないようにしている
  • print_background: true で背景色を出力している

まとめ

請求書HTMLテンプレートの主要な設計ポイント:

  • @page ルールでA4・余白を固定: 環境に左右されないレイアウト
  • 明細テーブルは縞模様 + 右揃え金額: 視認性の高いデザイン
  • 税率別内訳を必ず掲載: インボイス制度の適格請求書要件を満たす
  • thead の繰り返し設定: 複数ページでも列ヘッダーを常に表示

テンプレートが完成したら、請求書PDFの自動生成でAPIを使った月次バッチ処理・メール送信の自動化に進みましょう。APIの呼び出し全般はAPIドキュメントで確認できます。PDF生成が完了したらWebhookで完了通知を受け取るフローも合わせて実装することをおすすめします。

関連リンク

Powered by FUNBREW PDF