{/* This page is auto-generated from the skill's SKILL.md by website/scripts/generate-skill-docs.py. Edit the source SKILL.md, not this page. */}

Pdf

PDF 文件:创建、读取、合并、填表、OCR、编辑文本。

Skill 元数据

来源内置(默认安装)
路径skills/productivity/pdf
版本1.1.0
作者Nous Research
许可证MIT
平台linux, macos, windows
标签pdf, documents, forms, ocr, text-extraction, reportlab, pypdf, pdfplumber, pymupdf, marker
相关 skilldocx、xlsx、powerpoint

参考:完整 SKILL.md

INFO

以下是 Hermes 在触发该 skill 时加载的完整 skill 定义。这是 agent 在 skill 激活时所看到的指令内容。

PDF Skill

从结构化规格创建 PDF,构建并填写 AcroForm 表单(带布局 lint 和视觉叠加),提取文本/表/元数据,合并/拆分/旋转/加水印/盖戳页面,导出页面图像,管理元数据和附件,以及加密/解密——使用 pypdf、reportlab 和 pdfplumber。两项吸收来的能力位于 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,或 PATH 上 poppler 的 pdftoppm。脚本回退顺序 pypdfium2 → pdftoppm,两者都无时报告 {"rendered": false, "missing": [...]}(退出码 0)。
  • 每个辅助脚本惰性检查导入,依赖缺失时打印安装提示。

运行方式

所有辅助脚本位于 scripts/,是 argparse CLI——用 terminal 工具运行;每个都支持 --help。它们严格以 UTF-8 读写 JSON,向 stdout 打印 JSON 结果,失败时非零退出。

python scripts/pdf_create.py spec.json -o out.pdf         # 从 JSON 规格构建 PDF
python scripts/pdf_make_form.py formspec.json -o form.pdf # 从 JSON 规格构建可填 AcroForm
python scripts/pdf_form_layout.py formspec.json           # 构建前 lint 表单布局
python scripts/pdf_form_layout.py formspec.json --render-overlay boxes.png [--pdf form.pdf]
python scripts/pdf_read.py doc.pdf --text                 # 逐页文本(JSON)
python scripts/pdf_read.py doc.pdf --tables --csv-dir t/  # 表导出为 JSON + CSV 文件
python scripts/pdf_read.py doc.pdf --meta                 # 元数据、页面尺寸、加密/扫描标志
python scripts/pdf_read.py form.pdf --fields              # 表单字段:名、类型、值
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 platypuspdf_create.py spec.json -o out.pdf
构建可填表单reportlab acroFormpdf_make_form.py formspec.json -o form.pdf
lint 表单布局 / 叠加图pure python + PILpdf_form_layout.py formspec.json [--render-overlay o.png]
逐页文本pdfplumberpdf_read.py f.pdf --text
表 → JSON/CSVpdfplumberpdf_read.py f.pdf --tables
元数据 / 尺寸 / 加密 / 扫描pypdf + pdfplumberpdf_read.py f.pdf --meta
合并(+ 大纲)pypdfpdf_merge.py a.pdf b.pdf -o m.pdf
拆分 / 提取 / 旋转pypdfpdf_split.py f.pdf --pages 2-5 --rotate 90
列出 / 填写 / 压平表单pypdfpdf_read.py --fields、pdf_fill_form.py
加密 / 解密(AES-256)pypdfpdf_secure.py --encrypt/--decrypt
水印 / 盖 PDF 页戳pypdfpdf_watermark.py f.pdf --stamp w.pdf
按坐标盖文本/图像戳reportlab + pypdfpdf_stamp.py f.pdf --text "Sign here" --x 400 --y 60
页面 → PNG(审阅 / OCR 交接)pypdfium2 或 pdftoppmpdf_page_image.py f.pdf --pages 1-3 --out-dir imgs/
设置/清除元数据、附件pypdfpdf_meta.py --set-meta / --attach / --extract-attachments
压缩内容流pypdfpdf_split.py f.pdf --pages 1-N --compress

流程

  1. 先检查。 运行 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 skill——不要把空文本报为"无内容"。
  2. 创建。 用 write_file 写 JSON 规格(元素:heading、paragraph、table、image、pagebreak;可选 title/author 元数据;页码自动加),然后运行 pdf_create.py。布局重要时用 vision_analyze 在渲染页图上视觉验证。
  3. 提取。 --text 给出逐页字符串的 JSON 列表;--tables 给出每页行数组,还可发 CSV 文件。用 read_file 读结果;绝不要直接肉眼看二进制 PDF。
  4. 操作。 pdf_merge.py 拼接并可为每个源文件加一个书签;pdf_split.py 处理页范围(从 1 起,如 1-3,5,9-)、90° 步进旋转和 --compress。加水印先准备单页戳记 PDF(如经 pdf_create.py)再用 pdf_watermark.py 叠加;单行戳记("sign here"、斜 DRAFT、角落标签)用 pdf_stamp.py 按显式坐标盖文本或图像。
  5. 构建表单。 写一份 form-spec JSON(字段带 PDF 点单位的 label_box/entry_box——见 references/forms.md),用 pdf_form_layout.py lint 并修复每个报告问题,可选地用 vision_analyze 审阅 --render-overlay PNG,然后用 pdf_make_form.py 构建并用 pdf_read.py --fields 确认。
  6. 填写表单。 列字段(--fields)了解确切名和类型,用 write_file 写 UTF-8 JSON {"FieldName": "value"}(复选框接受 true/false;单选/选择值须匹配字段导出选项),然后 pdf_fill_form.py。用 --fields 重读确认值已落位。
  7. 元数据与附件。 pdf_meta.py --set-meta 写 Title/Author/Subject/Keywords(DocInfo);--clear-meta 丢弃它们;--attach/--list-attachments/--extract-attachments 往返嵌入式文件。
  8. 安全。 用不同的用户/所有者密码和 AES-256 加密。移除你知道的密码时,--decrypt 写一份未加密副本。
  9. 验证(见下)后再报成功。

常见陷阱

  • 扫描 PDF:空 extract_text() 加页面图像意味着无文本层。路由到 references/ocr-extraction.md;不要编造文本。
  • 压平限制:pdf_fill_form.py --flatten 用 pypdf 的压平支持,把小部件外观转为页面内容。对纯文本字段和复选框可靠,但可能丢弃或误渲染 exotic 小部件(富文本、自定义外观流、某些单选组)。用 vision_analyze 视觉验证压平输出;要万无一失的压平,用外部渲染器(如 Ghostscript 或 pdftoppm+重组)作回退。
  • NeedAppearances:填写后,查看器只在外观流存在时渲染值。填写脚本设 AcroForm NeedAppearances 标志,使合规查看器重新生成;某些极简查看器忽略它——显示保真重要时压平。
  • 非拉丁表单值:值存储正确(UTF-16),但字段默认字体可能缺字形,因此即使数据往返成功,查看器也可能显示空白。用 --fields 验证,而非仅视觉。
  • 压缩预期:--compress 只放气内容流。典型节省 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(如 gs -dPDFA=2 -dPDFACompatibilityPolicy=1 -sColorConversionStrategy=UseDeviceIndependentColor -sDEVICE=pdfwrite -o out.pdf in.pdf 配合合适 ICC profile),并用 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 列出每个 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 检查。