关于 pdf
pdf 是一项通过 Python 命令行脚本创建、提取、编辑和保护 PDF 文档的技能,涵盖结构化文档与 AcroForm 表单处理。OCR 和自然语言文本编辑则由单独的参考资料说明。
主要功能
- 01按结构化规范创建 PDF
- 02创建、填写和扁平化 AcroForm
- 03提取文本、表格和元数据
- 04合并、拆分、旋转和加水印
- 05管理附件及加密
适用场景
- 01生成 PDF 报告和发票
- 02创建并检查可填写表单
- 03将页面文本或表格提取为 JSON 或 CSV
- 04重排、盖章或保护 PDF 页面
安装
复制下面的命令,在终端中运行。
$
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 技能
使用 pypdf、reportlab 和 pdfplumber,根据结构化规范创建 PDF,构建并填写 AcroForm 表单(含布局 lint 检查和可视化叠加层),提取文本/表格/元数据,合并/拆分/旋转/添加水印/盖章页面,导出页面图像,管理元数据和附件,以及加密/解密。两个吸收的功能位于 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 表单(文本框/复选框/单选按钮/下拉框),并先对布局进行 lint 检查。
- 从 PDF 中提取文本、表格(JSON/CSV)、元数据或表单字段值。
- 合并、拆分、旋转、提取页面子集、添加水印、在指定坐标处盖文字/图像章、添加书签或压缩 PDF。
- 将页面导出为 PNG,以供目视检查或交由 OCR 处理;设置/清除文档元数据;添加/提取文件附件。
- 填写或扁平化 AcroForm 表单;使用密码加密或解密。
- 不适用于扫描件/纯图像 PDF(请使用
references/ocr-extraction.md),也不适用于像素级还原的 HTML 到 PDF 渲染(请使用无头浏览器)。
前置条件
- Python 3.10+,以及
pypdf、reportlab、pdfplumber:python -m pip install pypdf reportlab pdfplumber - 可选,用于页面栅格化(
pdf_page_image.py、叠加层渲染):python -m pip install pypdfium2,或将 poppler 的pdftoppm添加到 PATH。脚本按 pypdfium2 → pdftoppm 的顺序尝试;如果两者均不可用,则返回{"rendered": false, "missing": [...]}(退出码为 0)。 - 每个辅助脚本都会延迟检查导入依赖;如果缺少依赖,会打印安装提示。
运行方法
所有辅助脚本都位于 scripts/ 中,且都是 argparse CLI — 请使用 terminal 工具运行;每个脚本都支持 --help。它们严格以 UTF-8 格式读写 JSON,将 JSON 结果打印到 stdout,并在失败时以非零状态码退出。
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 |
| 检查表单布局 / 叠加图像 | 纯 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 或 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会合并文件,并可为每个源文件添加一个书签;pdf_split.py支持页码范围(从 1 开始,例如1-3,5,9-)、以 90° 为步长旋转,以及--compress。添加水印时,先准备单页印章 PDF(例如使用pdf_create.py),再用pdf_watermark.py叠加;对于“在此签名”、对角线 DRAFT、角落标签等单行印章,请使用pdf_stamp.py,并在指定坐标处添加文本或图像。 - 构建表单。 编写一个表单规范 JSON(字段使用 PDF 点作为单位的
label_box/entry_box——参见references/forms.md),使用pdf_form_layout.py检查并修复报告的所有问题;也可以使用vision_analyze检查--render-overlayPNG,然后使用pdf_make_form.py构建,并通过pdf_read.py --fields确认。 - 填写表单。 列出字段(
--fields)以了解准确的名称和类型,使用write_file编写 UTF-8 JSON,格式为{"FieldName": "value"}(复选框接受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或手动清理。 - 页面索引:辅助命令行工具使用从 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,询问是否存在重叠、未对齐,以及标签与对应字段脱离的情况。反复执行「规范 → lint → 叠加层」,直到没有问题。 - 构建表单后:
pdf_read.py form.pdf --fields会列出规范中的每个字段及其正确类型和选项。 - 填写表单后:运行
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