PDF 处理指南
概览
本技能覆盖常见 PDF 工作流(Python + 命令行)。
若要填写 PDF 表单,请额外阅读 forms.md;更深入的扩展能力可看 reference.md。
快速开始
from pypdf import PdfReader, PdfWriter
reader = PdfReader("document.pdf")
print(f"Pages: {len(reader.pages)}")
text = ""
for page in reader.pages:
text += page.extract_text()
Python 库
pypdf(基础结构处理)
合并
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)
拆分
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(meta.title, meta.author, meta.subject, meta.creator)
旋转页面
reader = PdfReader("input.pdf")
writer = PdfWriter()
page = reader.pages[0]
page.rotate(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:
print(page.extract_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"Table {j+1} on page {i+1}:")
for row in table:
print(row)
进阶:多表拼接
import pandas as pd
import pdfplumber
all_tables = []
with pdfplumber.open("document.pdf") as pdf:
for page in pdf.pages:
for table in page.extract_tables():
if table:
all_tables.append(pd.DataFrame(table[1:], columns=table[0]))
if all_tables:
pd.concat(all_tables, ignore_index=True).to_excel("extracted_tables.xlsx", index=False)
reportlab(新建 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, "This is a PDF created with reportlab")
c.line(100, height - 140, 400, height - 140)
c.save()
多页文档
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 = []
story.append(Paragraph("Report Title", styles["Title"]))
story.append(Spacer(1, 12))
story.append(Paragraph("This is the body of the report. " * 20, styles["Normal"]))
story.append(PageBreak())
story.append(Paragraph("Page 2", styles["Heading1"]))
story.append(Paragraph("Content for page 2", styles["Normal"]))
doc.build(story)
下标/上标(关键)
不要直接用 Unicode 下标/上标字符(在默认字体里容易显示为黑方块)。
用 Paragraph 的标记语法:
from reportlab.platypus import Paragraph
from reportlab.lib.styles import getSampleStyleSheet
styles = getSampleStyleSheet()
chemical = Paragraph("H<sub>2</sub>O", styles["Normal"])
squared = Paragraph("x<super>2</super> + y<super>2</super>", styles["Normal"])
命令行工具
pdftotext
pdftotext input.pdf output.txt
pdftotext -layout input.pdf output.txt
pdftotext -f 1 -l 5 input.pdf output.txt
qpdf
qpdf --empty --pages file1.pdf file2.pdf -- merged.pdf
qpdf input.pdf --pages . 1-5 -- pages1-5.pdf
qpdf input.pdf output.pdf --rotate=+90:1
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
常见任务模板
扫描版 OCR
import pytesseract
from pdf2image import convert_from_path
images = convert_from_path("scanned.pdf")
text = ""
for i, image in enumerate(images):
text += f"Page {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 -j input.pdf output_prefix
加密
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)
快速索引
| 任务 | 推荐 |
|---|---|
| 合并/拆分/旋转 | pypdf |
| 文本/表格提取 | pdfplumber |
| 新建 PDF | reportlab |
| 命令行流水线 | qpdf/pdftotext |
| OCR | pytesseract + pdf2image |
| 表单填写 | 先读 forms.md |
下一步
- 进阶技巧看 reference.md
- 表单填写严格按 forms.md
More from marcelleon/skills-zh
pptx
只要任务与 .pptx 有关(输入、输出或两者都有),就应触发本技能。包括:创建演示文稿、读取提取内容、修改现有模板、合并拆分页面、处理版式/讲稿/批注等。用户提到 deck/slides/presentation 或具体 .pptx 文件时,即便最终用途是摘要或邮件,也应使用本技能。
11xlsx
当用户任务以电子表格文件为核心输入或输出时必须使用本技能。涵盖 .xlsx/.xlsm/.csv/.tsv 的读取、清洗、修复、建模、公式计算、格式化、图表、模板更新与格式转换。用户只要提到某个表格文件路径并要求处理或产出表格,都应触发本技能。若主要交付物不是电子表格(如 Word/HTML/数据库流水线/Google Sheets API 集成),则不应触发。
10frontend-design
创建具有高设计质量的独特、生产级前端界面。当用户要求构建 Web 组件、页面、工件、海报或应用程序时使用此技能(示例包括网站、落地页、仪表板、React 组件、HTML/CSS 布局,或为任何 Web UI 设置样式/美化时)。生成富有创意、精美的代码和 UI 设计,避免通用的 AI 美学。
10slack-gif-creator
用于创建针对 Slack 优化的动画 GIF 的知识和实用工具。提供约束、验证工具和动画概念。当用户请求 Slack 的动画 GIF 时使用,例如"为 Slack 制作一个 X 做 Y 的 GIF"。
9canvas-design
使用设计哲学创建精美的 .png 和 .pdf 文档视觉艺术。当用户要求创建海报、艺术作品、设计或其他静态作品时,您应该使用此技能。创建原创的视觉设计,绝不复制现有艺术家的作品以避免侵犯版权。
8docx
当用户需要创建、读取、编辑或转换 Word 文档(.docx)时必须使用本技能。触发场景包括:提到 Word/docx、报告/备忘录/正式函件输出、目录和页眉页脚、批注或修订模式、替换文档内容、插入或替换图片、从 docx 提取结构化内容等。若目标交付物是 .docx,本技能应优先触发。不要用于 PDF、电子表格、Google Docs API 或无关编程任务。
7