Communitygithub.com

TMYTiMidlY/skills

PDF ファイルの読み取り、テキスト抽出、結合、分割、回転、パスワード保護など、あらゆる PDF 処理を実行するためのスキルです。

skills とは?

このスキルは、Python ライブラリ (pypdf, pdfplumber, reportlab) とコマンドラインツール (pdftotext, qpdf, pdftk) を使用して、PDF ファイルの包括的な処理を支援します。主な機能には、テキストおよび表の抽出、PDF の結合・分割、ページ回転、メタデータ抽出、OCR によるスキャン PDF からのテキスト抽出、透かしの追加、パスワード保護などが含まれます。各操作に対して具体的なコード例と CLI コマンドが提供されており、ユーザーはすぐに実装できます。このスキルは、開発者や AI エージェントがドキュメント処理パイプラインを効率的に構築するのに役立ち、特に Python とコマンドラインの両方に対応している点が強みです。また、ReportLab における Unicode 下付き/上付き文字の使用禁止など、実践的な注意点もカバーしています。

対応~Claude Code~Codex CLI~Cursor
npx skills add TMYTiMidlY/skills

お気に入りのAIに質問する

このエージェントスキルを事前に読み込んだ状態で新しいチャットを開きます。

ドキュメント

PDF 処理ガイド

概要

このガイドでは、Python ライブラリとコマンドラインツールを使用した基本的な PDF 処理操作について説明します。高度な機能、JavaScript ライブラリ、詳細な例については、REFERENCE.md を参照してください。PDF フォームに入力する必要がある場合は、FORMS.md を読んでその指示に従ってください。

クイックスタート

from pypdf import PdfReader, PdfWriter

# PDF を読み込む
reader = PdfReader("document.pdf")
print(f"ページ数: {len(reader.pages)}")

# テキストを抽出
text = ""
for page in reader.pages:
    text += page.extract_text()

Python ライブラリ

pypdf - 基本操作

PDF の結合

from pypdf import PdfWriter, PdfReader

writer = PdfWriter()
for pdf_file in ["doc1.pdf", "doc2.pdf", "doc3.pdf"]:
    reader = PdfReader(pdf_file)
    for page in reader.pages:
        writer.add_page(page)

with open("merged.pdf", "wb") as output:
    writer.write(output)

PDF の分割

reader = PdfReader("input.pdf")
for i, page in enumerate(reader.pages):
    writer = PdfWriter()
    writer.add_page(page)
    with open(f"page_{i+1}.pdf", "wb") as output:
        writer.write(output)

メタデータの抽出

reader = PdfReader("document.pdf")
meta = reader.metadata
print(f"タイトル: {meta.title}")
print(f"作成者: {meta.author}")
print(f"件名: {meta.subject}")
print(f"作成プログラム: {meta.creator}")

ページの回転

reader = PdfReader("input.pdf")
writer = PdfWriter()

page = reader.pages[0]
page.rotate(90)  # 時計回りに 90 度回転
writer.add_page(page)

with open("rotated.pdf", "wb") as output:
    writer.write(output)

pdfplumber - テキストと表の抽出

レイアウトを保持したテキスト抽出

import pdfplumber

with pdfplumber.open("document.pdf") as pdf:
    for page in pdf.pages:
        text = page.extract_text()
        print(text)

表の抽出

with pdfplumber.open("document.pdf") as pdf:
    for i, page in enumerate(pdf.pages):
        tables = page.extract_tables()
        for j, table in enumerate(tables):
            print(f"ページ {i+1} の表 {j+1}:")
            for row in table:
                print(row)

高度な表抽出

import pandas as pd

with pdfplumber.open("document.pdf") as pdf:
    all_tables = []
    for page in pdf.pages:
        tables = page.extract_tables()
        for table in tables:
            if table:  # 表が空でないことを確認
                df = pd.DataFrame(table[1:], columns=table[0])
                all_tables.append(df)

# すべての表を結合
if all_tables:
    combined_df = pd.concat(all_tables, ignore_index=True)
    combined_df.to_excel("extracted_tables.xlsx", index=False)

reportlab - PDF の作成

基本的な PDF 作成

from reportlab.lib.pagesizes import letter
from reportlab.pdfgen import canvas

c = canvas.Canvas("hello.pdf", pagesize=letter)
width, height = letter

# テキストを追加
c.drawString(100, height - 100, "Hello World!")
c.drawString(100, height - 120, "これは reportlab で作成された PDF です")

# 線を追加
c.line(100, height - 140, 400, height - 140)

# 保存
c.save()

複数ページの PDF 作成

from reportlab.lib.pagesizes import letter
from reportlab.platypus import SimpleDocTemplate, Paragraph, Spacer, PageBreak
from reportlab.lib.styles import getSampleStyleSheet

doc = SimpleDocTemplate("report.pdf", pagesize=letter)
styles = getSampleStyleSheet()
story = []

# コンテンツを追加
title = Paragraph("レポートタイトル", styles['Title'])
story.append(title)
story.append(Spacer(1, 12))

body = Paragraph("これはレポートの本文です。" * 20, styles['Normal'])
story.append(body)
story.append(PageBreak())

# 2 ページ目
story.append(Paragraph("2 ページ目", styles['Heading1']))
story.append(Paragraph("2 ページ目のコンテンツ", styles['Normal']))

# PDF を生成
doc.build(story)

下付き文字と上付き文字

重要: ReportLab PDF では、Unicode の下付き/上付き文字 (₀₁₂₃₄₅₆₇₈₉、⁰¹²³⁴⁵⁶⁷⁸⁹) を決して使用しないでください。組み込みフォントにはこれらのグリフが含まれておらず、黒い塗りつぶされた四角形として表示されてしまいます。

代わりに、Paragraph オブジェクトで ReportLab の XML マークアップタグを使用してください。

from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet

styles = getSampleStyleSheet()

# 下付き文字: <sub> タグを使用
chemical = Paragraph("H<sub>2</sub>O", styles['Normal'])

# 上付き文字: <super> タグを使用
squared = Paragraph("x<super>2</super> + y<super>2</super>", styles['Normal'])

キャンバス描画テキスト (Paragraph オブジェクト以外) の場合は、Unicode の下付き/上付き文字を使用する代わりに、フォントサイズと位置を手動で調整してください。

コマンドラインツール

pdftotext (poppler-utils)

# テキストを抽出
pdftotext input.pdf output.txt

# レイアウトを保持してテキストを抽出
pdftotext -layout input.pdf output.txt

# 特定のページを抽出
pdftotext -f 1 -l 5 input.pdf output.txt  # ページ 1〜5

qpdf

# PDF の結合
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf

# ページの分割
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
qpdf input.pdf --pages . 6-10 -- pages6-10.pdf

# ページの回転
qpdf input.pdf output.pdf --rotate=+90:1  # 1 ページ目を 90 度回転

# パスワードの解除
qpdf --password=mypassword --decrypt encrypted.pdf decrypted.pdf

pdftk (利用可能な場合)

# 結合
pdftk file1.pdf file2.pdf cat output merged.pdf

# 分割
pdftk input.pdf burst

# 回転
pdftk input.pdf rotate 1east output rotated.pdf

一般的なタスク

スキャン PDF からのテキスト抽出

# 実行方法: uv run --with pytesseract --with pdf2image script.py
import pytesseract
from pdf2image import convert_from_path

# PDF を画像に変換
images = convert_from_path('scanned.pdf')

# 各ページを OCR
for i, image in enumerate(images):
    text += f"ページ {i+1}:\n"
    text += pytesseract.image_to_string(image)
    text += "\n\n"

print(text)

透かしの追加

from pypdf import PdfReader, PdfWriter

# 透かしを作成(または既存のものを読み込む)
watermark = PdfReader("watermark.pdf").pages[0]

# すべてのページに適用
reader = PdfReader("document.pdf")
writer = PdfWriter()

for page in reader.pages:
    page.merge_page(watermark)
    writer.add_page(page)

with open("watermarked.pdf", "wb") as output:
    writer.write(output)

画像の抽出

# pdfimages を使用 (poppler-utils)
pdfimages -j input.pdf output_prefix

# これにより、すべての画像が output_prefix-000.jpg、output_prefix-001.jpg などとして抽出されます。

パスワード保護

from pypdf import PdfReader, PdfWriter

reader = PdfReader("input.pdf")
writer = PdfWriter()

for page in reader.pages:
    writer.add_page(page)

# パスワードを追加
writer.encrypt("userpassword", "ownerpassword")

with open("encrypted.pdf", "wb") as output:
    writer.write(output)

クイックリファレンス

タスク最適なツールコマンド/コード
PDF の結合pypdfwriter.add_page(page)
PDF の分割pypdf1 ファイルに 1 ページ
テキスト抽出pdfplumberpage.extract_text()
表の抽出pdfplumberpage.extract_tables()
PDF の作成reportlabCanvas または Platypus
コマンドライン結合qpdfqpdf --empty --pages ...
スキャンPDFのOCRpytesseractまず画像に変換
PDFフォームへの入力pdf-lib または pypdf (FORMS.md 参照)FORMS.md を参照

次のステップ

  • pypdfium2 の高度な使用法については、REFERENCE.md を参照してください
  • JavaScript ライブラリ (pdf-lib) については、REFERENCE.md を参照してください
  • PDF フォームに入力する必要がある場合は、FORMS.md の指示に従ってください
  • トラブルシューティングガイドについては、REFERENCE.md を参照してください

関連スキル