Use Cases

How to Implement PDF Generation with Claude Code

Learn how to implement pdf generation using Claude Code. Includes practical code examples and step-by-step guidance.

PDF生成をClaude Codeで効率的に実装する

請求書、レポート、帳票などのPDF出力は業務アプリで頻出する機能です。Claude Codeなら、テンプレート設計からPDF生成ロジックまで一括で実装できます。

jsPDFで請求書を生成する

軽量なjsPDFライブラリを使った請求書生成の例です。

> jsPDFで日本語対応の請求書PDFを生成する関数を作って。
> 会社名、宛先、明細行、合計金額を含めて。
import { jsPDF } from "jspdf";

interface InvoiceItem {
  description: string;
  quantity: number;
  unitPrice: number;
}

interface InvoiceData {
  invoiceNumber: string;
  date: string;
  companyName: string;
  clientName: string;
  items: InvoiceItem[];
  taxRate: number;
}

export function generateInvoice(data: InvoiceData): jsPDF {
  const doc = new jsPDF();
  const pageWidth = doc.internal.pageSize.getWidth();

  // Header
  doc.setFontSize(24);
  doc.text("請求書", pageWidth / 2, 30, { align: "center" });

  doc.setFontSize(10);
  doc.text(`請求書番号: ${data.invoiceNumber}`, pageWidth - 20, 50, { align: "right" });
  doc.text(`発行日: ${data.date}`, pageWidth - 20, 57, { align: "right" });

  // Recipient
  doc.setFontSize(14);
  doc.text(`${data.clientName} 御中`, 20, 70);

  doc.setFontSize(10);
  doc.text(data.companyName, pageWidth - 20, 70, { align: "right" });

  // Line items table
  let y = 90;
  doc.setFillColor(240, 240, 240);
  doc.rect(20, y, pageWidth - 40, 10, "F");
  doc.text("項目", 25, y + 7);
  doc.text("数量", 110, y + 7);
  doc.text("単価", 135, y + 7);
  doc.text("金額", 165, y + 7);

  y += 15;
  let subtotal = 0;

  data.items.forEach((item) => {
    const amount = item.quantity * item.unitPrice;
    subtotal += amount;

    doc.text(item.description, 25, y);
    doc.text(String(item.quantity), 115, y);
    doc.text(`$${item.unitPrice.toLocaleString()}`, 135, y);
    doc.text(`$${amount.toLocaleString()}`, 165, y);
    y += 10;
  });

  // Total
  const tax = Math.floor(subtotal * data.taxRate);
  const total = subtotal + tax;

  y += 5;
  doc.line(120, y, pageWidth - 20, y);
  y += 10;
  doc.text(`小計: $${subtotal.toLocaleString()}`, 165, y, { align: "right" });
  y += 8;
  doc.text(`消費税(${data.taxRate * 100}%): $${tax.toLocaleString()}`, 165, y, { align: "right" });
  y += 10;
  doc.setFontSize(14);
  doc.text(`合計: $${total.toLocaleString()}`, 165, y, { align: "right" });

  return doc;
}

PuppeteerでHTMLからPDF変換

複雑なレイアウトの場合、HTMLテンプレートからPDFを生成する方法が便利です。

import puppeteer from "puppeteer";

interface ReportData {
  title: string;
  date: string;
  sections: { heading: string; content: string }[];
  chartImageBase64?: string;
}

export async function generateReportPdf(data: ReportData): Promise<Buffer> {
  const html = `
    <!DOCTYPE html>
    <html>
    <head>
      <style>
        body { font-family: 'Noto Sans JP', sans-serif; margin: 40px; color: #333; }
        h1 { color: #1e40af; border-bottom: 2px solid #1e40af; padding-bottom: 8px; }
        h2 { color: #374151; margin-top: 24px; }
        .header { display: flex; justify-content: space-between; align-items: center; }
        .date { color: #6b7280; }
        .section { margin-bottom: 20px; page-break-inside: avoid; }
        .chart { text-align: center; margin: 20px 0; }
        @page { margin: 20mm; }
      </style>
    </head>
    <body>
      <div class="header">
        <h1>${data.title}</h1>
        <span class="date">${data.date}</span>
      </div>
      ${data.sections.map((s) => `
        <div class="section">
          <h2>${s.heading}</h2>
          <p>${s.content}</p>
        </div>
      `).join("")}
      ${data.chartImageBase64 ? `
        <div class="chart">
          <img src="data:image/png;base64,${data.chartImageBase64}" width="600" />
        </div>
      ` : ""}
    </body>
    </html>
  `;

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(html, { waitUntil: "networkidle0" });

  const pdf = await page.pdf({
    format: "A4",
    printBackground: true,
  });

  await browser.close();
  return Buffer.from(pdf);
}

APIエンドポイントとしてPDFを配信

生成したPDFをAPIから直接ダウンロードできるようにします。

// Next.js App Router
export async function GET(request: Request) {
  const { searchParams } = new URL(request.url);
  const invoiceId = searchParams.get("id");

  const invoiceData = await getInvoiceFromDB(invoiceId!);
  const doc = generateInvoice(invoiceData);
  const pdfBuffer = doc.output("arraybuffer");

  return new Response(pdfBuffer, {
    headers: {
      "Content-Type": "application/pdf",
      "Content-Disposition": `attachment; filename="invoice-${invoiceId}.pdf"`,
    },
  });
}

画像処理と組み合わせたい場合は画像処理の自動化を、スプレッドシートとの連携はスプレッドシート連携をご覧ください。

Summary

Claude Codeを使えば、jsPDFによる軽量な帳票生成から、Puppeteerを使ったリッチなレポート出力まで、PDF生成機能を短時間で実装できます。テンプレートの調整や日本語フォント対応も自然言語で指示できます。

詳しくはClaude Code公式ドキュメントを参照してください。

#Claude Code #PDF generation #jsPDF #Puppeteer #reports