跳到主要内容

Pdf

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

技能元数据​

SourceBundled (installed by default)
Pathskills/productivity\pdf
Version1.1.0
AuthorNous Research
LicenseMIT
Platformslinux, macos, windows
Tagspdf, documents, forms, ocr, text-extraction, reportlab, pypdf, pdfplumber, pymupdf, marker
Related skillsdocx, xlsx, powerpoint

参考:完整 SKILL.md​

信息

以下是 Hermes 在该技能被触发时加载的完整技能定义。这就是技能激活时智能体看到的指令内容。

PDF 技能

从结构化规格创建 PDF,构建并填写 AcroForm 表单(带布局检查与可视化叠加层),提取文本/表格/元数据,合并/拆分/旋转/水印/盖章页面,导出页面图像,管理元数据与附件,以及加密/解密——使用 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(文本/复选框/单选按钮/下拉列表),并先检查布局。
  • 从 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 platypuspdf_create.py spec.json -o out.pdf
构建可填充表单reportlab acroFormpdf_make_form.py formspec.json -o form.pdf
检查表单布局 / 叠加图像纯 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 技能 —— 不要将空文本报告为“无内容”。
  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. 构建表单。 编写一份表单规格 JSON(字段使用 PDF 点单位的 label_box/entry_box —— 见 references/forms.md),用 pdf_form_layout.py 检查并修复每一处报告的问题,可选地用 vision_analyze 审阅 --render-overlay 生成的 PNG,然后用 pdf_make_form.py 构建,并用 pdf_read.py --fields 确认。
  6. 填充表单。 列出字段(--fields)以了解确切的名称与类型,用 write_file 编写 {"FieldName": "value"} 的 UTF-8 JSON(复选框接受 true/false;单选/选择值必须匹配字段的导出选项),然后运行 pdf_fill_form.py。再次用 --fields 读取以确值确已写入。
  7. 元数据与附件。 pdf_meta.py --set-meta 写入标题/作者/主题/关键词(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 的扁平化支持,会将控件外观转换为页面内容。它对纯文本字段和复选框可靠,但可能丢失或错误渲染特殊控件(富文本、自定义外观流、部分单选组)。用 vision_analyze 视觉验证扁平化输出;若要万无一失的扁平化,回退到外部渲染器(例如 Ghostscript 或 pdftoppm+重组)。
  • NeedAppearances:填充后,查看器只有在存在外观流时才会渲染值。填充脚本会设置 AcroForm 的 NeedAppearances 标志,以便符合规范的查看器重新生成这些流;一些精简查看器会忽略它 —— 若显示保真度重要,则进行扁平化。
  • 非拉丁表单值:值会被正确存储(UTF-16),但字段的默认字体可能缺少字形,因此即便数据往返无误,查看器也可能显示空白。用 --fields 验证,而不仅是视觉查看。
  • 压缩预期:--compress 仅对内容流进行 deflate。典型节省为 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 配置文件),并用 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(红色 = 带字段名的输入框,蓝色 = 标签框),检查重叠、错位以及标签与其字段脱离的情况。不断迭代 spec → lint → overlay,直至干净。
  • 构建表单后: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 检查。