mcpField
P
PDF Generator

PDF Generator

github.com/jmsktmドキュメント10239 回インストール40 週間前に更新
リポジトリ

PDF Generator について

PDF Generator は、Markdown、HTML、テキスト、構造化データから PDF を作成・編集するスキルです。Node.js ライブラリを使い、書式付きレポートや一括変換、透かし、PDF 結合を行う手順を示します。

主な機能

  1. 01Markdown と HTML の PDF 変換
  2. 02ページ分割されたレポートの生成
  3. 03HTML ファイルの一括変換
  4. 04テキストまたは画像の透かし追加
  5. 05PDF 文書の結合
  6. 06文書メタデータの設定

活用シーン

  1. 01Markdown 文書を PDF として出力
  2. 02データから複数ページのレポートを作成
  3. 03ディレクトリ内の HTML を一括変換
  4. 04PDF に透かしを付ける、または結合

インストール

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

$npx skills add https://github.com/jmsktm/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を並列生成するには、ワーカースレッドを使用します

コメント