PDF 处理·免费版
原创免费技能。用开源库 pypdf / reportlab / pdfplumber / pytesseract 处理 PDF:合并拆分、文本表格提取、水印、表单填充、加密、OCR 与生成。所有指令均为本技能原创,仅依赖开源库。
红线(不可违反)
- 不泄密:处理含个人/商业敏感信息的 PDF 时,输出仅在用户指定路径,不在日志/对话里粘贴敏感内容
- 不编造内容:提取结果如实反映原文,不臆改
- 不引导付费:本技能为免费版,不引用任何付费端点
- 可运行交付:脚本基于真实开源 API,能直接跑
- OCR 标来源:OCR 结果是识别近似值,交付时提示「OCR 文本可能含识别误差,关键处请核对原件」
何时使用
- 合并/拆分/旋转 PDF
- 提取文本或表格(做台账、存档)
- 加水印、加密解密
- 填写 PDF 表单
- 扫描件 OCR 转可搜索
- 用 reportlab 从头生成 PDF(报告/证书/单据)
反触发:要编辑成可改写的 Word → 先提取再转 Word 技能;只是预览 → 用 pdftotext 即可。
职责边界
- 本技能负责:上述 PDF 操作与生成
- 本技能不负责:破解受版权保护且无权处理的加密文件、伪造签章
5 分钟上手(复制即出成品)
下面这段脚本独立可跑,pip install pypdf pdfplumber reportlab 后直接执行,不需要任何现成 PDF——
它自己造输入,然后走完一条完整流水线:生成 → 合并 → 叠中文水印 → 提文字 → 抽表格 → 加密。
# RUN: fixture=empty
from reportlab.lib.pagesizes import A4
from reportlab.pdfgen import canvas
from reportlab.pdfbase import pdfmetrics
from reportlab.pdfbase.cidfonts import UnicodeCIDFont
pdfmetrics.registerFont(UnicodeCIDFont("STSong-Light")) # reportlab 自带的中文字体
# ---- 1) 造输入:一份带完整网格线的表格页 + 一份纯文字页 ----
def make(name, title, rows=None):
c = canvas.Canvas(name, pagesize=A4)
c.setFont("Helvetica-Bold", 16); c.drawString(50, 800, title)
if rows:
XS, Y0, DY = [50, 150, 250, 350], 740, 30
for r_i, row in enumerate(rows):
x = 60
for v in row:
c.setFont("Helvetica-Bold" if r_i == 0 else "Helvetica", 11)
c.drawString(x, Y0 - r_i * DY - 20, str(v)); x += 100
# 横线 + 竖线都要画,缺竖线 pdfplumber 就拼不出格子
for i in range(len(rows) + 1):
c.line(XS[0], Y0 - i * DY, XS[-1], Y0 - i * DY)
for x in XS:
c.line(x, Y0, x, Y0 - len(rows) * DY)
c.showPage(); c.save()
make("a.pdf", "Sales Report", [["Region", "Q1", "Q2"], ["East", 12, 19], ["West", 5, 9]])
make("b.pdf", "Notes")
# ---- 2) 合并 ----
from pypdf import PdfReader, PdfWriter, Transformation
w = PdfWriter()
for f in ["a.pdf", "b.pdf"]:
for pg in PdfReader(f).pages:
w.add_page(pg)
with open("merged.pdf", "wb") as o: w.write(o)
print("合并页数:", len(PdfReader("merged.pdf").pages))
# ---- 3) 中文水印页 ----
wc = canvas.Canvas("wm.pdf", pagesize=A4)
wc.setFillAlpha(0.18)
wc.setFont("STSong-Light", 48)
wc.saveState(); wc.translate(300, 420); wc.rotate(45)
wc.drawCentredString(0, 0, "机密"); wc.restoreState()
wc.showPage(); wc.save()
# ---- 4) 叠加到每一页(带旋转/透明必须用 merge_transformed_page)----
wm = PdfReader("wm.pdf").pages[0]
w2 = PdfWriter()
for pg in PdfReader("merged.pdf").pages:
pg.merge_transformed_page(wm, Transformation().rotate(0))
w2.add_page(pg)
with open("watermarked.pdf", "wb") as o: w2.write(o)
# ---- 5) 提取文字 ----
txt = "\n".join(p.extract_text() for p in PdfReader("watermarked.pdf").pages)
print("文字含 'Sales Report':", "Sales Report" in txt, "| 含水印 '机密':", "机密" in txt)
# ---- 6) 抽表格(pdfplumber 默认按线条找格子)----
import pdfplumber
with pdfplumber.open("a.pdf") as pdf:
tables = pdf.pages[0].extract_tables()
print("抽到表格:", tables)
# ---- 7) 加密 / 解密 ----
w3 = PdfWriter()
for pg in PdfReader("merged.pdf").pages:
w3.add_page(pg)
w3.encrypt("userpass", "ownerpass")
with open("encrypted.pdf", "wb") as o: w3.write(o)
rr = PdfReader("encrypted.pdf")
print("是否加密:", rr.is_encrypted)
rr.decrypt("userpass") # pypdf 6.x 返回 PasswordType 枚举,别对它 len()
print("解密后页数:", len(rr.pages))
print("已生成 merged.pdf / watermarked.pdf / encrypted.pdf")
这段脚本里最容易踩的三个坑
- 抽不到表格多半是线没画全:pdfplumber 默认
lines策略靠横竖线交叉找格子,
只画横线不画竖线 →extract_tables()返回[]。真没有线时改用
{"vertical_strategy": "text", "horizontal_strategy": "text"} - 中文水印要注册 CID 字体:
UnicodeCIDFont("STSong-Light"),直接用 Helvetica 写中文会变黑块 - 叠加水印用
merge_transformed_page不是merge_page:前者才支持旋转/缩放,
且decrypt()在 pypdf 6.x 返回枚举,不要拿它当列表取长度
主流程
常用参考:references/snippets.md(合并/拆分/旋转/抽表/水印/加密/OCR 单文件操作)、references/batch.md(批量流水线、加密跳过、表单盘点与填值)。
第 1 步:判断任务类型
| 任务 | 主库 |
|---|---|
| 合并/拆分/旋转/水印/加密 | pypdf |
| 提取文本/表格 | pdfplumber |
| 从头生成 | reportlab |
| 扫描件 OCR | pytesseract + pdf2image |
质检闸 1:任务类型不明时先确认,选错库会返工。
第 2 步:执行
- 合并:
PdfWriter逐页add_page - 提取表格:
pdfplumberextract_tables()→ 可转 DataFrame/Excel - 生成:
reportlabPlatypus(标题/正文/表格/分页);禁止用 Unicode 上下标字符,改用<sub>/<super>标签 - OCR:
convert_from_path→image_to_string,逐页拼接
质检闸 2:生成 PDF 用 Platypus 结构化,避免坐标硬编码导致错位;上下标用标签。
第 3 步:校验
- 合并/拆分后页数正确
- 提取文本用
pdftotext -layout抽查与原文一致 - 生成 PDF 转图目检排版
质检闸 3:结果正确、无乱码再交付。
第 4 步:自检清单
- [ ] 操作类型与所用库匹配
- [ ] 合并/拆分页数正确
- [ ] 提取文本/表格忠实原文
- [ ] 生成 PDF 排版正常、无上下标黑块
- [ ] OCR 结果已提示「可能含误差」
- [ ] 敏感信息未外泄
- [ ] 无付费引导话术残留
- [ ] 文件可正常打开
失败降级
- 库未装 → 对应
pip install pypdf pdfplumber reportlab pytesseract pdf2image - OCR 依赖缺失 → 提示安装 Tesseract + 中文语言包
- 加密文件无权限 → 说明无法处理并建议合法途径
- 复杂表单 → 用 pdf-lib 思路,但优先 pypdf
依赖
pypdf、pdfplumber、reportlab(均 BSD/MIT)、可选 pytesseract+pdf2image(OCR)、poppler-utils(命令行提取)。无专有组件。
相关技能推荐
ppt-free— AI 一键生成 PPT / 幻灯片 / 演示文稿(.pptx):工作总结、汇报、路演、课件、产品介绍。内置版式配色与图表规范,中文排版,开源excel-free— Excel 表格自动生成与处理(.xlsx):报表、台账、预算、数据清洗、图表可视化。支持公式、条件格式、多 Sheet,中文财务配色,开源cad-free— CAD 建模 / Mechanical Design:开源参数化建模与工程图 — 零件建模、标准件库、装配体、尺寸驱动、STEP/STL/Dsheetmetal-free— 钣金设计与展开:K 因子与折弯扣除计算、展开长度推导、折弯半径与最小孔边距规则、工艺缺口与让位、DXF 展开图输出与下料清单
致谢
本技能为原创,仅使用开源库。与任何厂商的专有 PDF 技能无隶属、无复制关系。