pdf について
pdfは、PythonのコマンドラインスクリプトでPDFの作成、抽出、編集、保護を行うスキルです。構造化文書とAcroFormの処理を扱い、OCRと自然言語によるテキスト編集は別のリファレンスで案内します。
主な機能
- 01構造化仕様からPDFを作成
- 02AcroFormの作成、入力、フラット化
- 03テキスト、表、メタデータの抽出
- 04ページの結合、分割、回転、透かし追加
- 05添付ファイルと暗号化の管理
活用シーン
- 01PDF形式のレポートや請求書を作成
- 02入力可能なフォームの作成と検証
- 03ページのテキストや表をJSONまたはCSVに抽出
- 04PDFページの並べ替え、スタンプ、保護
インストール
コマンドをコピーしてターミナルで実行します。
$
npx skills add https:/ / github.com/ nousresearch/ hermes-agent --skill pdfインストール後、Claude Code で/pdfを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
LICENSEreferences/forms.mdnano-pdf-editing.mdocr-extraction.mdscripts/_raster.pyextract_marker.pyextract_pymupdf.pypdf_create.pypdf_fill_form.pypdf_form_layout.pypdf_make_form.pypdf_merge.pypdf_meta.pypdf_page_image.pypdf_read.pypdf_secure.pypdf_split.pypdf_stamp.pypdf_watermark.pytests/test_pdf_skill.py詳細
PDF スキル
構造化仕様から PDF を作成し、AcroForm フォームを構築・入力(レイアウト検査と視覚的オーバーレイ付き)します。テキスト/表/メタデータを抽出し、ページの結合/分割/回転/透かし/スタンプ、ページ画像のエクスポート、メタデータと添付ファイルの管理、暗号化/復号を行います。pypdf、reportlab、pdfplumber を使用します。取り込まれた 2 つの機能は references/ にあります。該当する作業の前に対応するファイルを読んでください。
- スキャン画像のみの PDF と OCR(pymupdf の高速パス、marker-pdf の高品質パス、scripts/extract_pymupdf.py + scripts/extract_marker.py):
references/ocr-extraction.md - 自然言語プロンプトを使った既存 PDF 内のテキスト編集(nano-pdf CLI):
references/nano-pdf-editing.md
使用する場面
- レポート、請求書、複数ページの文書を PDF として生成する場合。
- JSON 仕様から入力可能な AcroForm(テキスト/チェックボックス/ラジオボタン/ドロップダウン)を構築し、事前にレイアウトを検査する場合。
- PDF からテキスト、表(JSON/CSV)、メタデータ、フォームフィールドの値を取得する場合。
- PDF の結合、分割、回転、ページ部分集合の抽出、透かしやテキスト/画像の座標指定によるスタンプ、ブックマークの追加、圧縮を行う場合。
- 目視確認や OCR への引き渡し用にページを PNG としてエクスポートする場合、文書のメタデータを設定/消去する場合、ファイル添付を追加/抽出する場合。
- AcroForm フォームに入力またはフラット化する場合、パスワードで暗号化/復号する場合。
- スキャン画像のみの PDF には使用しないでください(
references/ocr-extraction.mdを使用)。ピクセル単位で正確な HTML から PDF へのレンダリングにも使用しないでください(ヘッドレスブラウザーを使用)。
前提条件
pypdf、reportlab、pdfplumberをインストールした Python 3.10 以降:python -m pip install pypdf reportlab pdfplumber- ページのラスタライズ(
pdf_page_image.py、オーバーレイのレンダリング)にはオプションで、python -m pip install pypdfium2、または PATH 上の poppler のpdftoppmが必要です。スクリプトは pypdfium2 → pdftoppm の順にフォールバックし、どちらも見つからない場合は{"rendered": false, "missing": [...]}を報告します(終了コード 0)。 - 各ヘルパースクリプトはインポートを遅延して確認し、依存関係が不足している場合はインストール方法を表示します。
実行方法
すべてのヘルパーは scripts/ にあり、argparse の CLI として実行します。terminal ツールから実行してください。いずれも --help に対応しています。JSON の読み書きには UTF-8 のみを使用し、JSON の結果を標準出力に出力します。失敗時はゼロ以外の終了コードで終了します。
python scripts/pdf_create.py spec.json -o out.pdf # build PDF from JSON spec
python scripts/pdf_make_form.py formspec.json -o form.pdf # build fillable AcroForm from JSON spec
python scripts/pdf_form_layout.py formspec.json # lint form layout BEFORE building
python scripts/pdf_form_layout.py formspec.json --render-overlay boxes.png [--pdf form.pdf]
python scripts/pdf_read.py doc.pdf --text # per-page text (JSON)
python scripts/pdf_read.py doc.pdf --tables --csv-dir t/ # tables to JSON + CSV files
python scripts/pdf_read.py doc.pdf --meta # metadata, page sizes, encrypted/scanned flags
python scripts/pdf_read.py form.pdf --fields # form fields: name, type, value
python scripts/pdf_merge.py a.pdf b.pdf -o merged.pdf [--bookmarks]
python scripts/pdf_split.py doc.pdf --pages 1-3,7 -o part.pdf [--rotate 90]
python scripts/pdf_fill_form.py form.pdf --fields-json values.json -o filled.pdf [--flatten]
python scripts/pdf_secure.py doc.pdf --encrypt -o enc.pdf --user-password your-password
python scripts/pdf_secure.py enc.pdf --decrypt -o dec.pdf --password your-password
python scripts/pdf_watermark.py doc.pdf --stamp mark.pdf -o stamped.pdf [--under]
python scripts/pdf_stamp.py doc.pdf -o out.pdf --text "DRAFT" --x 150 --y 400 \
--font-size 60 --rotation 45 --opacity 0.3 --color "#cc0000" [--pages 1-3]
python scripts/pdf_stamp.py doc.pdf -o out.pdf --image sig.png --x 400 --y 60 --width 120
python scripts/pdf_page_image.py doc.pdf --pages 1-3 --dpi 150 --out-dir imgs/
python scripts/pdf_meta.py doc.pdf --set-meta --title "T" --author "A" -o out.pdf
python scripts/pdf_meta.py doc.pdf --attach data.csv -o out.pdf
python scripts/pdf_meta.py doc.pdf --list-attachments | --extract-attachments dir/
クイックリファレンス
| タスク | ツール | コマンド/API |
|---|---|---|
| 文書の作成(見出し、表、画像) | reportlab platypus | pdf_create.py spec.json -o out.pdf |
| 入力可能なフォームの構築 | reportlab acroForm | pdf_make_form.py formspec.json -o form.pdf |
| フォームレイアウトの検査/オーバーレイ画像 | pure python + PIL | pdf_form_layout.py formspec.json [--render-overlay o.png] |
| ページごとのテキスト | pdfplumber | pdf_read.py f.pdf --text |
| 表 → JSON/CSV | pdfplumber | pdf_read.py f.pdf --tables |
| メタデータ/サイズ/暗号化/スキャン状態 | pypdf + pdfplumber | pdf_read.py f.pdf --meta |
| 結合(アウトライン付き) | pypdf | pdf_merge.py a.pdf b.pdf -o m.pdf |
| 分割/抽出/回転 | pypdf | pdf_split.py f.pdf --pages 2-5 --rotate 90 |
| フォームの一覧表示/入力/フラット化 | pypdf | pdf_read.py --fields, pdf_fill_form.py |
| 暗号化/復号(AES-256) | pypdf | pdf_secure.py --encrypt/--decrypt |
| PDF ページの透かし/スタンプ | pypdf | pdf_watermark.py f.pdf --stamp w.pdf |
| 座標指定によるテキスト/画像のスタンプ | reportlab + pypdf | pdf_stamp.py f.pdf --text "Sign here" --x 400 --y 60 |
| ページ → PNG(確認/OCR への引き渡し) | pypdfium2 or pdftoppm | pdf_page_image.py f.pdf --pages 1-3 --out-dir imgs/ |
| メタデータと添付ファイルの設定/消去 | pypdf | pdf_meta.py --set-meta / --attach / --extract-attachments |
| コンテンツストリームの圧縮 | pypdf | pdf_split.py f.pdf --pages 1-N --compress |
手順
- まず確認します。
pdf_read.py file.pdf --metaを実行します。encrypted(true の場合は、まずpdf_secure.py --decryptで復号します)とlikely_scanned_pagesを確認します。ページが画像のみの場合は、pdf_page_image.py --pages <scanned> --dpi 300 --out-dir imgs/でエクスポートし、PNG をreferences/ocr-extraction.mdのスキルに渡します。テキストが空だからといって「コンテンツなし」と報告してはいけません。 - 作成します。
write_fileで JSON 仕様を記述します(要素:heading、paragraph、table、image、pagebreak。title/authorメタデータは任意。ページ番号は自動で追加されます)。次にpdf_create.pyを実行します。レイアウトが重要な場合は、レンダリングしたページ画像をvision_analyzeで確認します。 - 抽出します。
--textはページごとの文字列の JSON リストを返します。--tablesはページごとの行配列を返し、CSV ファイルも出力できます。read_fileで結果を読み取ります。バイナリ PDF を直接目視で確認してはいけません。 - 加工します。
pdf_merge.pyはファイルを連結し、ソースファイルごとにブックマークを 1 つ追加できます。pdf_split.pyはページ範囲(1 始まり。例:1-3,5,9-)、90°単位の回転、--compressに対応しています。透かしを入れるには、(例:pdf_create.pyを使って)1 ページのスタンプ PDF を用意し、pdf_watermark.pyで重ねます。「ここに署名」などの 1 行スタンプ、斜めの DRAFT、隅のラベルには、テキストまたは画像を明示した座標に配置できるpdf_stamp.pyを使います。 - フォームを作成します。 フォーム仕様の JSON を 1 つ記述します(フィールドの
label_box/entry_boxは PDF ポイント単位です。references/forms.mdを参照)。pdf_form_layout.pyで検査し、報告された問題をすべて修正します。必要に応じて--render-overlayの PNG をvision_analyzeで確認してから、pdf_make_form.pyで作成し、pdf_read.py --fieldsで確認します。 - フォームに入力します。 フィールド名と型を正確に把握するため、フィールドを一覧表示(
--fields)します。write_fileで{"FieldName": "value"}形式の UTF-8 JSON を記述します(チェックボックスにはtrue/falseを指定できます。ラジオボタンや選択肢の値は、フィールドのエクスポートオプションと一致させる必要があります)。次にpdf_fill_form.pyを実行します。値が反映されたことを確認するため、--fieldsで再読み込みします。 - メタデータと添付ファイル。
pdf_meta.py --set-metaは Title/Author/Subject/Keywords(DocInfo)を書き込みます。--clear-metaはこれらを削除します。--attach/--list-attachments/--extract-attachmentsは、埋め込みファイルの追加・一覧表示・抽出を行います。 - 保護します。 ユーザーパスワードとオーナーパスワードを別々に設定し、AES-256 で暗号化します。知っているパスワードを削除するには、
--decryptを実行すると暗号化されていないコピーが作成されます。 - 成功を報告する前に、下記を参照して確認します。
注意点
- スキャンされた PDF:
extract_text()が空で、ページ画像がある場合、テキストレイヤーはありません。references/ocr-extraction.mdに従って処理し、テキストを捏造しないでください。 - フラット化の制限:
pdf_fill_form.py --flattenは pypdf のフラット化サポートを使用し、ウィジェットの外観をページコンテンツに変換します。通常のテキストフィールドやチェックボックスでは信頼性がありますが、特殊なウィジェット(リッチテキスト、カスタム外観ストリーム、一部のラジオボタングループ)では、表示が欠落したり、誤って描画されたりすることがあります。フラット化した出力をvision_analyzeで目視確認してください。確実にフラット化するには、代替手段として外部レンダラー(Ghostscript やpdftoppmと再構成など)を使用してください。 - NeedAppearances:入力後、外観ストリームが存在する場合にのみ、ビューアーに値が表示されます。入力スクリプトは AcroForm の
NeedAppearancesフラグを設定し、準拠したビューアーに外観を再生成させます。簡易的なビューアーの中にはこのフラグを無視するものもあるため、表示の忠実度が重要な場合はフラット化してください。 - 非ラテン文字のフォーム値:値は正しく(UTF-16 で)保存されますが、フィールドのデフォルトフォントに字形がない場合、データを往復して取得できてもビューアーでは空白に見えることがあります。目視だけでなく、
--fieldsで確認してください。 - 圧縮の想定:
--compressが deflate するのはコンテンツストリームのみです。通常、削減率は 0~20%です。画像が大半を占める PDF や、すでに圧縮済みのストリームには効果がありません。画像のダウンサンプリング(Ghostscript の領域)の代わりにはなりません。 - 権限フラグでは強制できない:所有者パスワードの権限ビット(印刷禁止、コピー禁止)は、ビューアーが尊重する場合もある任意の制限です。pypdf を含むあらゆるライブラリで読み取り、解除できます。コンテンツへのアクセスを暗号化によって実際に制限するのは、ユーザーパスワードだけです。権限フラグをセキュリティとして提示しないでください。
- 表の抽出はヒューリスティックです:pdfplumber は罫線や単語の配置から表を検出します。罫線のない表やセルが結合された表では、
table_settingsの調整や手作業での修正が必要になることがあります。 - ページ番号の扱い:ヘルパー CLI は 1 始まりのページ番号を受け取ります。pypdf API は 0 始まりです。スクリプト側で変換するため、二重に変換しないでください。
- 回転したスタンプのテキスト抽出:pdfplumber の行グループ化では、回転した字形の順序が乱れます(45° 回転した「DRAFT」がばらばらの文字として抽出されます)。回転したスタンプは、
pypdfのextract_text()またはレンダリング画像で確認してください。 - ラジオボタングループ:reportlab ではグループごとに 2 個以上の
radio()ウィジェットが必要です。入力にはスラッシュ付きのエクスポート値("/red")が必要です。また、フラット化の忠実度が最も低いのはラジオボタンです。references/forms.mdを参照してください。 - メタデータの範囲:
pdf_meta.pyが書き込むのは従来の DocInfo ディクショナリのみです。埋め込み XMP メタデータ(存在する場合)は変更されず、一部のビューアーでは異なる値が表示されることがあります。 - PDF/A は対象外です:pypdf と reportlab では、準拠した PDF/A を生成または検証できません。アーカイブ適合性が必要な場合は、
terminalツールを通じて Ghostscript を実行し(例:適切な ICC プロファイルを指定してgs -dPDFA=2 -dPDFACompatibilityPolicy=1 -sColorConversionStrategy=UseDeviceIndependentColor -sDEVICE=pdfwrite -o out.pdf in.pdf)、veraPDF で検証してください。どちらも外部インストールが必要です。また、結果は想定で済ませず、検証する必要があります。 - 回転角度は 90 の倍数である必要があります。暗号化された入力は、ほかの操作を行う前に復号してください。
検証
- 作成/結合/分割後:
pdf_read.py out.pdf --metaを実行し、page_countと、回転した場合はページごとのrotationを確認します。 - 抽出後:JSONが空でないことを確認し、既知の文字列またはセルを抜き取り確認します。
- フォームの設計ループ:
pdf_form_layout.py spec.jsonが終了コード0で終了する必要があります。次に、--render-overlay boxes.png --pdf form.pdfを実行し、vision_analyzeでPNGを確認します。重なり、位置ずれ、フィールドから離れたラベルがないか確認します。問題がなくなるまで、spec → lint → overlayを繰り返します。 - フォームの作成後:
pdf_read.py form.pdf --fieldsを実行し、spec内のすべてのフィールドが正しい型と選択肢で一覧表示されることを確認します。 - フォームへの入力後:
pdf_read.py filled.pdf --fieldsを実行し、値を比較します(非ASCII文字を含め、完全一致すること)。 - スタンプ後:テキストを再抽出するか(回転したスタンプにはpypdfを使用)、
pdf_page_image.pyでページをレンダリングし、vision_analyzeで確認します。 - メタデータ/添付ファイルの編集後:
pdf_read.py --meta/pdf_meta.py --list-attachmentsを実行し、添付ファイルを再抽出してバイト単位で比較します。 - 暗号化後:
--metaに"encrypted": trueと表示され、パスワードなしでは開けないことを確認します。復号後は、テキスト抽出結果が元の内容と一致することを確認します。 - 視覚的な要素(透かし、フラット化したフォームなど)は、レンダリングして
vision_analyzeで確認します。
コメント
Markdown 対応