关于 PdfPecker
PdfPecker 是用于将 HTML 和 Markdown 转为 PDF,以及提取或渲染 PDF 内容的 Python 库和 MCP 服务。其内置原生引擎无需浏览器、网络访问或 Python 依赖。
主要功能
- 01将 HTML 和 Markdown 转为 PDF
- 02将 PDF 页面渲染为图像
- 03提取 PDF 文本和 Markdown
- 04合并 PDF 并转换为 PDF/A
- 05将 MCP 文件访问限制在指定目录
适用场景
- 01从 HTML 或 Markdown 文档生成 PDF
- 02预览 PDF 页面并提取内容
- 03合并 PDF 或生成 PDF/A 文件
- 04让 MCP 客户端在获准目录中创建和检查文件
MCP 相关
该软件包内含 MCP 服务,通过 stdio 提供 PDF 创建、渲染、提取、合并和转换工具。文件访问仅限于配置的根目录。
配置
本地服务的配置在各客户端中通用,复制后粘贴到客户端的 MCP 配置文件即可。
工具
8收录的工具列表 · 更新于 4 天前
| 参数 | 类型 | 必填 | 说明 |
|---|---|---|---|
| html | string | 否 | HTML 文档。提供此项或 html_path。 |
| fonts | array | 否 | CSS font-family 可引用的字体文件或文件夹(.ttf、.otf、.woff2)。处理拉丁文、希腊文和西里尔文以外的文字时需要。 |
| title | string | 否 | 文档标题;默认值:HTML <title>。 |
| author | string | 否 | |
| margin | number | 否 | 页面边距,单位为点(每英寸 72 点),默认值为 36。@page margin 优先。 |
| preview | boolean | 否 | 同时返回首页图像(最多 3 页,60 dpi),用于检查布局。默认值为 true。 |
| language | string | 否 | 文档语言,例如 en-GB。 |
| html_path | string | 否 | 要转换的 HTML 文件。请提供此项或 html。 |
| landscape | boolean | 否 | 将页面方向旋转为横向。 |
| page_size | string | 否 | A3、A4、A5、Letter、Legal(默认 A4),或以 mm 为单位的 WIDTHxHEIGHT,例如 100x150。CSS @page size 规则优先。 |
| conformance | enum | 否 | 生成归档用 PDF/A 文件。PDF/A-2b | PDF/A-3b | PDF/A-2u | PDF/A-3u | PDF/A-4 | PDF/A-4f |
| footer_text | string | 否 | 每页底部的一行文字,例如 "Page {page} of {pages}"。 |
| header_text | string | 否 | 每页顶部的一行文字;{page} 和 {pages} 会被替换。 |
| output_path | string | 是 | 要写入的 PDF 文件。 |
| accessibility | enum | 否 | 生成带标签(无障碍)的 PDF。tagged | PDF/UA-1 | PDF/UA-2 |
| use_system_fonts | boolean | 否 | 同时使用此计算机上安装的字体。 |
详细介绍
Python 版 pdfpecker
为 Python 提供快速的 HTML 和 Markdown 转 PDF,以及 PDF 转图片和文本功能。无需浏览器、依赖项或安装 .NET。
pip install pdfpecker
import pdfpecker
pdf = pdfpecker.html_to_pdf("<h1>Invoice 42</h1><p>Total: <b>1,250.00 EUR</b></p>")
pdfpecker.html_file_to_pdf("templates/invoice.html", "invoice.pdf") # images and CSS resolve next to the file
pdfpecker.markdown_file_to_pdf("README.md", "readme.pdf")
pngs = pdfpecker.pdf_to_images(pdf, dpi=96) # one PNG per page (or format="jpeg"/"webp")
text = pdfpecker.pdf_to_text(pdf) # pages separated by \f
both = pdfpecker.merge_pdfs([pdf, "terms.pdf"])
这是 PdfPecker .NET 库,已提前编译为原生库并打包在 wheel 中。PdfPecker 拥有自己的 HTML 解析器、CSS 引擎、布局引擎、PDF 写入器和 PDF 渲染器,因此将一页发票转换为 PDF 大约只需 1 毫秒,而且不会启动浏览器。 软件包版本即其所包含的库版本。关于 PdfPecker 的渲染内容、CSS 支持及其限制,请参阅:pdfpecker.net/docs。
平台
适用于 Python 3.9 及更高版本的 wheel,支持 Linux(glibc 2.28+ 和 musl,x86-64 和 ARM64)、macOS(Apple Silicon 和 Intel)及 Windows(x64 和 ARM64)。每个 wheel 大约 9 MB,且没有 Python 或系统依赖项。
速度
在一台 4 核 Linux 云虚拟机上通过 Python 测得,预热后每个文档的中位耗时;文档为 PdfPecker 仓库中的基准测试页面:
| 发票,1 页 | 功能介绍,5 页 | 报告,29 页 | 启动并生成首个 PDF | 峰值内存,单个 PDF | |
|---|---|---|---|---|---|
| pdfpecker | 0.7 ms | 2.9 ms | 32 ms | 57 ms | 32 MB |
| Chromium 153 via Playwright | 24 ms | 48 ms | 290 ms | 735 ms | 542 MB |
| xhtml2pdf 0.2.28 | 33 ms | 209 ms | 2.9 s | 453 ms | 63 MB |
| WeasyPrint 70.0 | 324 ms | 797 ms | 4.2 s | 1.1 s | 75 MB |
API
每个函数都接受 PDF 的字节数据或路径,失败时会引发 PdfPeckerError 的子类,且线程安全,并会在运行期间释放 GIL,因此多个线程可以并行转换。
| 函数 | 返回值 |
|---|---|
html_to_pdf(html, **options) | 根据 HTML str 或 UTF-8 bytes 生成的 PDF 字节数据 |
html_file_to_pdf(path, output=None, **options) | PDF 字节数据;如果指定了 output,也会写入该路径;base_dir 为文件所在文件夹 |
markdown_to_pdf(markdown, **options) | 根据支持 GitHub 表格、任务列表、删除线和脚注的 CommonMark 生成的 PDF 字节数据 |
markdown_file_to_pdf(path, output=None, **options) | 与 html_file_to_pdf 相同 |
pdf_to_images(pdf, dpi=150, format="png", pages=None, width=None, height=None, transparent=False, quality=None, password=None) | 编码后图像的列表,每页一张 |
pdf_to_text(pdf, pages=None, password=None) | 按阅读顺序排列的文本,各页之间以 \f 分隔 |
pdf_to_text_pages(pdf, pages=None, password=None) | 包含每页文本的列表 |
pdf_to_markdown(pdf, pages=None, include_links=True, include_annotations=True, include_images=False, page_comments=False, max_pages=None, password=None) | 将任意 PDF 转为 GitHub Flavored Markdown,按阅读顺序排列标题、列表和表格,适用于搜索索引和大模型 |
pdf_page_count(pdf, password=None) | 页数 |
merge_pdfs(pdfs, title=None, author=None, bookmarks=True, creation_date=None) | 将多个 PDF 合并为一个 PDF |
pdf_to_pdfa(pdf, output=None, conformance="PDF/A-2b") | 将任意 PDF 转为 PDF/A-2b、-2u、-3b 或 -3u,并以 PdfAResult 返回,其中包含 pdf、changes、problems 和 is_conformant |
library_version() | 内部 PdfPecker 库的版本 |
pages 可接受页码、页码列表或范围,例如 "1-3,5"、"8-" 或 "last";页码从 1 开始。
每个函数还都接受以秒为单位的 timeout。
HTML 和 Markdown 函数的选项:
| 选项 | 含义 |
|---|---|
base_dir | 相对图像、样式表和字体路径所依据的文件夹。若不设置,来自字符串的文档不会加载任何本地文件。 |
allow_file_access | 允许文档读取 base_dir 之外的文件。仅用于你信任的 HTML。 |
page_size、landscape | "A3"、"A4"(默认值)、"A5"、"Letter"、"Legal" 或 (width_mm, height_mm)。CSS @page { size } 规则优先。 |
margin | 以点为单位(每英寸 72 点):单个数值或 (top, right, bottom, left)。默认值为 36。CSS @page { margin } 优先。 |
scale、shrink_to_fit | 缩放内容;将宽于页面的内容缩小以适应页面(默认开启)。 |
header_text、footer_text | 位于上边距或下边距的文本行;{page} 和 {pages} 会被替换。CSS 页边距盒(@top-center 等)可实现更多效果。 |
fonts、use_system_fonts | CSS font-family 可指定的 TrueType/OpenType 文件或文件夹;也可在已安装字体中查找字体系列。 |
title、author、subject、keywords、language | 文档属性。 |
user_style_sheet | 在文档自身样式之后应用的 CSS。 |
creation_date | 固定日期(datetime、date 或 Unix 秒数):这样每次运行的输出字节都完全相同。 |
conformance | "PDF/A-2b"、"PDF/A-3b"、"PDF/A-2u"、"PDF/A-3u"、"PDF/A-4" 或 "PDF/A-4f"。 |
accessibility | "tagged"、"PDF/UA-1" 或 "PDF/UA-2"。 |
compress、bookmarks、max_pages | 压缩数据流(开启);根据标题生成书签(开启);超过此页数后停止(100,000)。 |
错误:选项无效时抛出 PdfPeckerArgumentError(也是 ValueError);输入不是可读取的 PDF 时抛出 PdfReadError;密码错误时抛出 PdfPasswordError;超过 max_pages 或大小限制时抛出 PdfLimitError;超时时抛出 PdfTimeoutError(也是 TimeoutError);无法读取字体或文件时抛出 PdfFileError(也是 OSError)。
在 AI Agent 和技能中使用
pdfpecker 适合在沙箱中编写并运行 Agent 代码:只需执行一次 pip install,运行时无需下载任何内容,
无需启动浏览器,出错时也会说明问题所在。可以告知 Agent 以下几点:
- 使用带 CSS 的 HTML 编写文档;在
@page规则中设置纸张大小、页边距、页码和页眉页脚, 例如@page { size: A4; margin: 20mm; @bottom-center { content: "Page " counter(page) " of " counter(pages) } }。 - 不支持 JavaScript:图表必须使用 SVG 或图片,不能使用绘制图表的脚本。
- 图片、样式表和字体从
base_dir(或data:URI)加载,绝不会从网络加载。 - 内置字体(Helvetica、Times 和 Courier,以及为它们缺少的字母附带的备用字体)支持拉丁文、希腊文和西里尔文;其他文字会显示为问号。对于中文、日文、阿拉伯文、希伯来文、印地文或泰文,请传入能覆盖相应文字的字体
fonts=[...],或设置use_system_fonts=True。 - 若要检查结果,可使用
pdf_to_images(pdf, dpi=60)将其渲染为图片并查看页面,或使用pdf_to_text读取内容。
MCP 服务
该软件包包含一个 Model Context Protocol 服务,因此支持 MCP 的聊天应用和编码 Agent 可以生成 PDF、查看其页面并读取内容。它通过 stdio 运行,只需安装此软件包:
claude mcp add pdfpecker -- uvx pdfpecker mcp # Claude Code
对于读取 mcpServers 设置的 Claude Desktop 和其他应用:
{ "mcpServers": { "pdfpecker": { "command": "uvx", "args": ["pdfpecker", "mcp", "--root", "/Users/me/Documents/pdfs"] } } }
| 工具 | 功能 |
|---|---|
html_to_pdf | 将 HTML(内联内容或文件)转换为 PDF 文件,并提供前几页的预览以检查版式 |
markdown_to_pdf | 同上,但用于 Markdown |
render_pdf_pages | 生成最多 20 页的 PNG 图片,供模型查看 |
pdf_to_text | 按页提取 PDF 文本 |
pdf_to_markdown | 将任意 PDF 转换为 Markdown,并返回结果或写入文件 |
pdf_to_pdfa | 将任意 PDF 转换为 PDF/A,并说明更改内容以及无法修复的问题 |
pdf_info | 查看页数和文件大小 |
merge_pdfs | 将多个 PDF 文件合并为一个 |
这些工具仅读取和写入 --root 文件夹内的文件(可重复指定),因为路径由模型选择。默认值为当前文件夹;如果服务在文件系统根目录中启动,则默认为 ~/PdfPecker,聊天应用经常会这样启动。python -m pdfpecker mcp 无需 uvx 即可运行同一服务。
从源代码构建
wheel 中的原生库由 PDFPECKER_VERSION 中指定的已发布 PdfPecker NuGet 软件包构建。
它需要 .NET 10 SDK 和 NativeAOT 前置条件(Linux 上的 clang、macOS 上的 Xcode、Windows 上的 Visual Studio C++
工具):
ci/build.sh linux-x64 manylinux_2_39_x86_64 # RID and wheel tag; builds, packs and tests the wheel
也可以手动构建:dotnet publish native/PdfPecker.Native.csproj -c Release -r linux-x64,将 pdfpecker_native.so
(.dylib、.dll)复制到 src/pdfpecker/,然后运行 pytest。PDFPECKER_NATIVE_LIB 用于指定其他位置的库。
C ABI(native/Exports.cs)包含一个函数:pdfpecker_invoke(op, input, input_len, options_json, &output, &output_len, &error),以及 pdfpecker_free、pdfpecker_version 和 pdfpecker_abi_version,因此其他具备 FFI 的语言也可以使用同一库。
发布
NuGet 上发布 PdfPecker 后,会在此处提交一个更改 PDFPECKER_VERSION 的拉取请求。合并后,
所有者会发布一个标记为 v<version> 的 GitHub 版本;Wheels 工作流会重新构建八个 wheel,检查
标签是否与 PDFPECKER_VERSION 一致,并通过 Trusted Publishing 将它们上传至 PyPI。随后,它会在官方 MCP Registry 中列出 MCP 服务的新版本(server.json)。
许可证
MIT。该 wheel 还包含 .NET 运行时、zlib-ng,以及 PdfPecker 随附的字体和数据,每项均有自己的
许可证:请参阅 THIRD-PARTY-NOTICES.md。
评论
一个开放协议,规定了 AI 应用如何以统一方式连接外部工具与数据源。客户端负责与模型对话,MCP 服务负责提供工具、资源和提示模板,两者通过标准消息通信,同一个服务可以被不同客户端复用。