mcpField

PDF Generator

github.com/eddiebe147ドキュメント61 回インストール
リポジトリ

PDF Generator について

PDF Generatorは、Markdown、HTML、テキスト、構造化データからPDFを作成するスキルです。レイアウト調整、レポート作成、透かし、ファイル結合に対応し、報告書や印刷用資料の作成に使えます。

主な機能

  1. 01MarkdownとHTMLのPDF変換
  2. 02複数ページのレポート作成
  3. 03テキストまたは画像の透かし追加
  4. 04複数PDFの結合
  5. 05ドキュメントメタデータ設定
  6. 06ページレイアウトと画像の処理

活用シーン

  1. 01ドキュメントのPDF書き出し
  2. 02構造化データからのレポート作成
  3. 03HTMLドキュメントの一括変換
  4. 04PDFへの透かし追加やファイル結合

インストール

コマンドをコピーしてターミナルで実行します。

$npx skills add https://github.com/eddiebe147/claude-settings --skill pdf-generator

インストール後、Claude Code で/pdf-generatorを入力して読み込まれたか確認します。

詳細

PDF ジェネレーター

PDF ジェネレーターのスキルを使うと、Markdown、HTML、プレーンテキスト、構造化データなど、さまざまなソースからプロフェッショナルな PDF ドキュメントを作成できます。書式設定、画像、メタデータ、透かし、複数ページのレイアウトに対応しています。このスキルでは、puppeteer、pdfkit、jsPDF などの Node.js ライブラリを活用し、包括的な PDF 生成機能を提供します。

ドキュメントを PDF に変換する場合、グラフ付きのレポートを生成する場合、印刷可能なフォームを作成する場合、クライアント向けの納品物を作成する場合など、このスキルはプログラムによって出版品質の PDF を作成するためのツールとワークフローを提供します。

主なワークフロー

ワークフロー 1:Markdown を PDF に変換する

目的: Markdown ファイルをスタイル付きの書式設定された PDF ドキュメントに変換します

手順:

  1. ソースの Markdown ファイルを読み込みます
  2. marked などのライブラリを使って Markdown を HTML に解析します
  3. プロフェッショナルな見た目になるよう CSS スタイルを適用します
  4. Puppeteer を使い、適切な改ページを設定して HTML を PDF としてレンダリングします
  5. メタデータ(タイトル、作成者、作成日)を追加します
  6. 指定された出力先に保存します

実装:

const puppeteer = require('puppeteer');
const marked = require('marked');
const fs = require('fs');

async function markdownToPdf(mdPath, outputPath, options = {}) {
  const markdown = fs.readFileSync(mdPath, 'utf8');
  const html = marked.parse(markdown);

  const styledHtml = `
    <!DOCTYPE html>
    <html>
    <head>
      <style>
        body { font-family: 'Helvetica', sans-serif; margin: 40px; line-height: 1.6; }
        h1 { color: #2c3e50; border-bottom: 2px solid #3498db; padding-bottom: 10px; }
        h2 { color: #34495e; margin-top: 30px; }
        code { background: #f4f4f4; padding: 2px 6px; border-radius: 3px; }
        pre { background: #f4f4f4; padding: 15px; border-radius: 5px; overflow-x: auto; }
        blockquote { border-left: 4px solid #3498db; padding-left: 20px; color: #7f8c8d; }
      </style>
    </head>
    <body>${html}</body>
    </html>
  `;

  const browser = await puppeteer.launch();
  const page = await browser.newPage();
  await page.setContent(styledHtml);
  await page.pdf({
    path: outputPath,
    format: 'A4',
    margin: { top: '20mm', right: '20mm', bottom: '20mm', left: '20mm' },
    printBackground: true,
    ...options
  });
  await browser.close();
}
ワークフロー 2:複数ページの PDF レポートを生成する

目的: ヘッダー、フッター、ページ番号、セクションを含む構成化されたレポートを作成します

手順:

  1. レポートの構成(表紙、目次、セクション、付録)を定義します
  2. PDFKit のドキュメントインスタンスを作成します
  3. タイトル、ロゴ、日付を含む表紙を追加します
  4. ページ番号を参照できる目次を生成します
  5. 一貫した書式設定でセクションを追加します
  6. 各ページにヘッダーとフッターを含めます
  7. ページ番号を追加して仕上げます

実装:

const PDFDocument = require('pdfkit');
const fs = require('fs');

function generateReport(data, outputPath) {
  const doc = new PDFDocument({
    size: 'A4',
    margins: { top: 50, bottom: 50, left: 50, right: 50 }
  });

  const stream = fs.createWriteStream(outputPath);
  doc.pipe(stream);

  // Cover page
  doc.fontSize(28)
     .text(data.title, { align: 'center' })
     .moveDown(2)
     .fontSize(14)
     .text(`Generated: ${new Date().toLocaleDateString()}`, { align: 'center' });

  doc.addPage();

  // Table of contents
  doc.fontSize(20).text('Table of Contents', { underline: true });
  doc.moveDown();
  data.sections.forEach((section, idx) => {
    doc.fontSize(12)
       .fillColor('blue')
       .text(`${idx + 1}. ${section.title}`, { link: `#section${idx}` })
       .fillColor('black');
  });

  // Sections
  data.sections.forEach((section, idx) => {
    doc.addPage();
    doc.fontSize(18)
       .fillColor('black')
       .text(section.title, { destination: `section${idx}` });
    doc.moveDown();
    doc.fontSize(11).text(section.content, { align: 'justify' });
  });

  // Add page numbers
  const pages = doc.bufferedPageRange();
  for (let i = 0; i < pages.count; i++) {
    doc.switchToPage(i);
    doc.fontSize(10)
       .text(`Page ${i + 1} of ${pages.count}`,
             50, doc.page.height - 50,
             { align: 'center' });
  }

  doc.end();
}
ワークフロー 3:HTML を一括で PDF に変換する

目的: 1 回の操作で複数の HTML ファイルを PDF に変換します

手順:

  1. ディレクトリ内の HTML ファイルを検索するか、ファイルリストを受け取ります
  2. Puppeteer のブラウザーインスタンスを設定します(効率化のため再利用します)
  3. 各 HTML ファイルについて、次の処理を行います:
    • HTML コンテンツを読み込みます
    • 標準のスタイルを適用します
    • 一貫した設定で PDF にレンダリングします
    • 対応するファイル名で保存します
  4. ブラウザーを閉じて、結果を報告します
ワークフロー 4:既存の PDF に透かしを追加する

目的: PDF ドキュメントにテキストまたは画像の透かしを適用します

手順:

  1. pdf-lib を使って既存の PDF を読み込みます
  2. すべてのページを取得します
  3. 各ページについて、次の処理を行います:
    • 透かしのテキストを描画します(斜め、半透明)
    • または、透かし画像を重ねます
  4. 変更した PDF を保存します
  5. 元のメタデータを保持します

実装:

const { PDFDocument, rgb, degrees } = require('pdf-lib');
const fs = require('fs');

async function addWatermark(inputPath, outputPath, watermarkText) {
  const existingPdfBytes = fs.readFileSync(inputPath);
  const pdfDoc = await PDFDocument.load(existingPdfBytes);
  const pages = pdfDoc.getPages();

  pages.forEach(page => {
    const { width, height } = page.getSize();
    page.drawText(watermarkText, {
      x: width / 2 - 100,
      y: height / 2,
      size: 48,
      color: rgb(0.75, 0.75, 0.75),
      opacity: 0.3,
      rotate: degrees(-45)
    });
  });

  const pdfBytes = await pdfDoc.save();
  fs.writeFileSync(outputPath, pdfBytes);
}
ワークフロー 5:複数の PDF を結合する

目的: 複数の PDF ドキュメントを 1 つのファイルにまとめます

手順:

  1. 新しい PDF ドキュメントを作成します
  2. 各ソース PDF を読み込みます
  3. 各ソースからすべてのページをコピーします
  4. 新しいドキュメントに追加します
  5. メタデータを統合した PDF を保存します

クイックリファレンス

操作コマンド/トリガー
Markdown を PDF に変換「[file.md] を PDF に変換」
データからレポートを生成「[data] から PDF レポートを作成」
HTML を一括変換「すべての HTML ファイルを PDF に変換」
透かしを追加「[file.pdf] に [text] の透かしを追加」
PDF を結合「[file1.pdf] と [file2.pdf] を結合」
ページを抽出「[file.pdf] から 1~5 ページを抽出」
PDF を圧縮「[file.pdf] を圧縮」
メタデータを追加「[file.pdf] の PDF メタデータを設定」

ベストプラクティス

  • ページサイズ: 一貫性を保つため、用紙サイズ(「A4」「Letter」)と向きを必ず指定します
  • 余白: 印刷できるように、最低15mmの余白を設定します
  • フォント: 互換性を確保するため、フォントを埋め込むか、標準PDFフォント(Helvetica、Times、Courier)を使用します
  • 画像: ファイルサイズを抑えるため、埋め込む前に画像を圧縮します
  • ファイルサイズ: PDFのサイズを確認し、5MBを超えるファイルには圧縮を使用します
  • アクセシビリティ: 可能な場合は、スクリーンリーダー向けにドキュメント構造タグを含めます
  • メタデータ: タイトル、作成者、作成日をメタデータに必ず設定します
  • 改ページ: ページ分割を制御するには、CSSのpage-break-beforeまたはpage-break-afterを使用します
  • テスト: 複数のビューアー(Adobe、Preview、ブラウザー)でPDFをテストします
  • セキュリティ: 機密文書には、パスワード保護と権限設定を提供します
  • 検証: アーカイブ品質が必要な場合は、PDF/Aへの準拠を確認します
  • バッチ処理: 複数のファイルを変換する場合は、ブラウザーインスタンスを再利用します

一般的なパターン

ドキュメントのエクスポート:

// Convert project README to PDF with styling
await markdownToPdf('./README.md', './docs/README.pdf', {
  headerTemplate: '<div style="font-size:10px; text-align:center;">Project Documentation</div>',
  footerTemplate: '<div style="font-size:10px; text-align:center;">Page <span class="pageNumber"></span></div>',
  displayHeaderFooter: true
});

請求書の生成:

// Create PDF invoice from template
const doc = new PDFDocument();
doc.pipe(fs.createWriteStream('invoice.pdf'));
doc.fontSize(20).text('INVOICE', { align: 'center' });
doc.fontSize(12).text(`Invoice #: ${invoiceNumber}`);
doc.text(`Date: ${date}`);
// ... add line items, totals, etc.
doc.end();

依存関係

必要なパッケージをインストールします:

npm install puppeteer pdfkit pdf-lib marked

エラー処理

  • ファイルが見つからない: 処理の前に、ソースファイルのパスを確認します
  • メモリの問題: 大きなPDFには、ストリーミングとチャンク処理を使用します
  • フォントエラー: カスタムフォントの読み込みに失敗した場合は、標準フォントにフォールバックします
  • レンダリングのタイムアウト: 複雑なページでは、Puppeteerのタイムアウトを延長します
  • 権限: 読み取り/書き込み権限エラーを適切に処理します

パフォーマンスのヒント

  • バッチ処理ではPuppeteerのブラウザーインスタンスを再利用します
  • 画像が多いファイルにはPDF圧縮を使用します
  • 繰り返し変換する場合は、レンダリング済みのHTMLをキャッシュします
  • 大きなPDFはすべてをメモリに読み込まず、ページごとに処理します
  • PDFを並列生成するには、ワーカースレッドを使用します

コメント