pdfpecker を使ったPDFの作成と読み取り
pdfpecker は、ブラウザを使わずにHTMLとCSS(またはMarkdown)をPDFに変換し、PDFのページを画像にレンダリングして作成結果を確認できます。以下の順序で作業してください。HTMLを作成→変換→ページを確認→修正→再度変換。
セットアップ
python3 -c "import pdfpecker" 2>/dev/null || python3 -m pip install --quiet pdfpecker
ヘルパースクリプトは、このスキルのフォルダ内の scripts/pdf.py です(Claude Codeの場合: ${CLAUDE_SKILL_DIR}/scripts/pdf.py)。
このスクリプトはパッケージをラップしているため、通常の作業ではPythonコードを自分で書く必要はありません。
python3 scripts/pdf.py html invoice.html invoice.pdf # 画像とCSSはHTMLファイルと同じフォルダから解決されます
python3 scripts/pdf.py md notes.md notes.pdf --page-size Letter
python3 scripts/pdf.py preview invoice.pdf --dpi 80 # invoice-page-1.png などを書き出し、パスを表示します
python3 scripts/pdf.py text report.pdf --pages 1-2
python3 scripts/pdf.py markdown report.pdf report.md # 任意のPDFをMarkdownに変換(表やリストも保持)
python3 scripts/pdf.py info report.pdf # ページ数
python3 scripts/pdf.py merge all.pdf cover.pdf report.pdf
すべてのオプションは python3 scripts/pdf.py <command> --help で確認できます。Pythonからは、同じ呼び出しが
pdfpecker.html_to_pdf(html, base_dir=...), html_file_to_pdf(path, out), markdown_to_pdf(text),
pdf_to_images(pdf, dpi=80), pdf_to_text(pdf), pdf_to_markdown(pdf), pdf_page_count(pdf), merge_pdfs([...])
および pdf_to_pdfa(pdf, "out.pdf")(既存PDFを長期保存用のPDF/Aに変換)として利用できます。
HTMLの作成
適切なテンプレートがあれば、そこから始めてください。templates/invoice.html(明細表付きの1ページ請求書)と
templates/report.html(表紙、ページ番号、ヘッダーが繰り返されるテーブル、SVGのチャートを含む複数ページのレポート)があります。
出力先の隣にコピーして編集してください。
ページレイアウトはオプションではなくCSSに記述してください。
@page {
size: A4; /* または Letter, A5, "A4 landscape", 210mm 99mm */
margin: 18mm 16mm 20mm;
@bottom-center { content: "Page " counter(page) " of " counter(pages); font: 9pt sans-serif; color: #666; }
}
@page :first { @bottom-center { content: none; } }
h2 { break-after: avoid; } /* 見出しと後続の内容が同じページに収まるように */
tr, figure, .card { break-inside: avoid; }
.new-page { break-before: page; }
thead { display: table-header-group; } /* すべてのページでヘッダーを繰り返す(<thead>のデフォルト) */
知っておくべきこと(詳細は reference.md を参照)。
- JavaScriptは動作しません。 スクリプトは実行されません。チャートはインラインSVGまたはCSS(サイズ指定した
<div>によるバーなど)で描画し、変換前にデータを埋め込んでください。 - ネットワークアクセスはありません。 画像、スタイルシート、フォントはHTMLファイルと同じフォルダ(
base_dir)またはdata:URI からのみ読み込まれ、http(s) URL からは読み込まれません。必要なものは事前にダウンロードするか、埋め込んでください。 - フォントについて。 独自のフォントがない場合、テキストはHelvetica(
sans-serif、Arial)、Times(serif)、Courier(monospace)と、同梱されたフォールバックフォントを使用します。これらはラテン文字、ギリシャ文字、キリル文字をカバーしています。中国語、日本語、韓国語、アラビア語、ヘブライ語、ヒンディー語、タイ語などは、それらを含むフォントを指定しないと?として出力されます。フォントを指定するには--font NotoSansSC-Regular.otfまたは--system-fonts(マシンにインストールされたフォントを使用)を指定します。特定の書体には、相対パスのsrcを持つ@font-faceを使用してください。 - モダンCSSが動作します。 flexbox、grid、テーブル、float、マルチカラム、ポジショニング、transform、グラデーション、シャドウ、角丸、
object-fit、SVG、Webフォント、カウンター、CSS変数など。Chromeの印刷プレビューと同様にレイアウトしてください。PdfPeckerはChromeのレイアウトに従います。 - 単位について。
mm、pt、またはpx(1インチあたり96px)を使用してください。A4で左右のマージンが16mmの場合、コンテンツ幅は178mm(約673px)です。
結果の確認
PDFを納品する前に必ずページを確認してください。preview を実行してPNGを表示します。テキストが切れたりページからはみ出していないか、テーブルや見出しがページをまたいで不適切に分割されていないか、新しいページに1行だけ残っていないか、空のページがないか、文字の代わりに?が表示されていないか(フォント欠落)、画像が読み込まれていないか(パス誤り)を確認してください。text で文言と順序を確認できます。HTMLやCSSを修正し、再度変換して、もう一度確認してください。
エラー
スクリプトはステータス1で終了し、原因を表示します。Pythonからは、すべてのエラーは pdfpecker.PdfPeckerError のサブクラスです。不適切なオプションは PdfPeckerArgumentError、読み取り可能なPDFでないファイルは PdfReadError、PdfPasswordError、PdfLimitError(ページ数が多すぎる)、PdfTimeoutError、読み取りできないフォントやファイルは PdfFileError となります。