ARTICLE · 1113823
OFD⇄PDF 选型决策树:别按榜单选,按这 5 个问题选
前两篇的结论可以浓缩成一句话:
榜单告诉你"在 6~7 个特定文件上谁快",不告诉你"在你的业务里谁对"。
这一篇是可直接拿去用的选型手册。
一、先做筛选:4 个问题砍掉一半选项
在看任何性能数字之前,先回答这四个问题。它们不是偏好问题,是能不能用的问题。
Q1 转换后的文件要能被搜索/复制/抽取吗?Q2 你的文档有签章/发票/复杂图形吗?Q3 体积有上限吗(上传限制、存储成本)?Q4 能进商用项目吗(许可证)?Q1 决定技术路线(一票否决)
这是最重要的一问,因为它直接决定你落在 01 篇那张四路线图的哪一层:
要可搜索/可复制 │ ├─ 是 → 只能走「路线 A:矢量重绘」 │ 候选(实测中表现最好者) │ OFD→PDF: go-zc310 / go-ofdgo / rust-easyofd │ java-ofdrw / node-ofd2pdf │ PDF→OFD: go-zc310 / go-ofdgo / node-jsofd │ └─ 否 → 路线 B/C/D 全都可用,按速度选 路线 B 轮廓化 java-ofdrw 体积涨 10~26 倍 路线 C 栅格化 python-pdf2ofd 最简单,0 文本 路线 D 抽取式 rust-easyofd ⚠️ 实测输出不可用⚠️ 路线 D(rust-easyofd 0.1.4 的 PDF→OFD)实测是不可用的:输出空页 / CID 乱码 / 版面固定 (10,20)。不要因为它"最快"就选它。
⚠️ 但这是版本 0.1.4 的状态。输出空页、CID 乱码属于"实现缺失",不是路线固有限制(对比:路线 B/C 丢文本才是固有的)—— 作者修掉它们只是时间问题。用之前先测当前版本。
Q2 决定验收样本
你的文档越复杂,越不能用 hello 验收:
zsbk | |
ano | |
intro | |
1000-pages | |
GBT_33190-2016 | |
GBT_33190-2016 |
Q3 决定能否用轮廓/栅格路线
实测体积比(输出 / 源):
go-zc310 0.43 ~ 1.43 ✅ 全部 ≤1.5xgo-ofdgo 0.52 ~ 2.59java-ofdrw 1.00 ~ 26.48 ⚠️python-pdf2ofd 1.04 ~ 20.63 ⚠️node-jsofd 2.08 ~ 29.25 ⚠️有体积上限的场景,java-ofdrw / pdf2ofd / jsOFD 基本可以划掉。
Q4 是硬门槛
ofd-libraries.md 收录 66 个库,其中 19 个标注「无」许可证。
实测参测的 8 个 OFD→PDF + 6 个 PDF→OFD 共 14 个转换器实例里(去重后 10 个底层库):
⚠️ jsyzdej/ofd2pdf → 无许可证 → 商用直接排除其余 13 个 → Apache-2.0 / MIT → 可用(仍需法务确认)⚠️ 未声明许可证 ≠ 免费可用。ofd-libraries.md 中"无"只表示该库未声明许可证;按通行做法,未声明即默认保留所有权利。这条比任何性能数据都优先。
二、OFD→PDF 决策树
你的 OFD → PDF 需求 │ ┌───────────────────────┼───────────────────────┐ ▼ ▼ ▼ 要文本可搜 复杂图形/版面 只要快/要小 │ │ │ ▼ ▼ ▼ go-zc310 go-ofdgo rust-easyofd 文本相似度 4 胜 intro 99.62% 最高 速度 5 胜 ano=7280 字符 hello/999 像素高 1000-pages 614KB 体积比接近数科 ⚠️ 必须自验 intro 类样本 │ │ │ └───────────┬───────────┴───────────┬───────────┘ ▼ ▼ Java 栈 → java-ofdrw Node → node-ofd2pdf 小文件接近数科 字符数 2 胜、intro 1.1MB 1000-pages 文本相似度最高 ⚠️ 体积大、速度慢一句话决策:
| go-zc310 | |
| go-ofdgo | |
| go-zc310 |
三、PDF→OFD 决策树
你的 PDF → OFD 需求 │ ┌───────────────────────┼───────────────────────┐ ▼ ▼ ▼ 要文本可搜 要像素级像 简单文档/演示 │ │ │ ▼ ▼ ▼ go-zc310 java-ofdrw python-pdf2ofd 唯一「可用+有序 hello 99.98% 最简单 +可提取」三者兼得 1000-pages 99.62% 999 像素最高 体积比 0.43~1.43 ⚠️ 0 文本 ⚠️ 0 文本 ano 99.75%(读注解) ⚠️ 10~26 倍体积 ⚠️ 1000 页 34.2s │ │ │ └───────┬───────────────┴───────────┬───────────┘ ▼ ▼ 复杂图形 → go-ofdgo Node 环境 → node-jsofd intro 99.80% 全场最高 提取量第二 提取量最大 ⚠️ 体积最大、相似度低一句话决策:
| 默认答案 | go-zc310 |
| 排除 rust-easyofd 0.1.4 |
四、选型矩阵(速查表)
OFD → PDF
| go-zc310 | ||||||
星级为依据实测数据的相对归纳,非官方评分。
☆表示该项实测明显短板。两处需注意:
python-ofd2pdf的"复杂版面"给 ★★★ —— 它在像素表里hello99.95%、1000-pages99.32% 各拿 1 胜(共 2 胜),但源文档同时标注其矢量图形不支持、无法提取文本,所以只给 3 星。速度一栏与"胜出次数"不完全对齐(如 go-zc310 0 胜仍给 3 星),因为星级综合了多页场景表现(
intro、1000-pages)而非单列第一。
PDF → OFD
| go-zc310 | ||||||
"读注解"一列的证据强度不同,请勿当作实测结论:
✅ go-zc310、go-ofdgo—— 源文档明确列出能力含"注解"❌ node-jsofd—— 源文档明确"不转换注解/渐变/图案/Type3/剪裁"- 未记录
java-ofdrw、 python-pdf2ofd、rust-easyofd—— 源文档只描述其技术路线(轮廓化 / 栅格化 / 抽取),未说明是否处理注解。go-zc310在ano上 99.75% 的高像素分只能间接说明源 PDF 里的 Stamp 被覆盖了,不能证明是"读注解"做到的。若你的文档大量依赖 PDF 注解(发票骑缝章等),这一列请自行验证。
五、组合拳:真实项目往往需要两套
单一库几乎总有短板。实测数据支持三种组合策略。
策略 A:文本优先(档案、公文、发票)
go-zc310 作为默认转换器 + 人工复核 / 像素门禁(阈值可设 98%) + 文本提取校验(字符数 > 0 且非乱码)关键:加一道"文本非乱码"检查。 这是 rust-easyofd 那类"有字符但是 CID 乱码"故障唯一的拦截点。
策略 B:分级路由(复杂业务)
简单文档(纯文本、少图、无签章) → go-zc310(快、体积小) 复杂文档(多层图形、背景图) → go-ofdgo(intro 99.62%) 签章/发票 → go-zc310(读 Stamp 注解)判定条件可用转换前的特征:文件大小、页数、是否含 Annots、是否含 Image 资源数量。
策略 C:双轨并行(高可靠归档)
轨道 1 go-zc310 → 保文本,供检索/抽取 轨道 2 java-ofdrw → 保外观,供忠实呈现/打印 两份都存,元数据记录来源轨道代价是存储翻倍(1000-pages 实测 3.1M vs 57.4M,差 18 倍)。先算清存储成本再上。
反模式(别这么干)
✗ 按"综合第一"选 —— 没有综合第一,各维度冠军是不同库✗ 只跑 hello 就验收 —— 67% 成功率的库 hello 也可能过✗ 用像素相似度验收可搜索性 —— 两者无关(go-ofdgo 99.62% / 文本 0)✗ 因为"快"就选 rust-easyofd 0.1.4 做 PDF→OFD —— 输出空页(但先测新版再排除)✗ 转换后就归档 —— 归档另需固定性验证与制度检查✗ 把转换后的签章外观当签名有效性 —— 信任链不随格式转换六、语言栈与许可的交叉筛选
技术之外,选型还要过两道非技术关。
6.1 语言栈决定你能部署什么
6.2 许可证
实测共 14 个转换器实例(OFD→PDF 8 个 + PDF→OFD 6 个),去重后对应 10 个底层库:
Apache-2.0 10 个实例 / 6 个库 go-zc310、go-ofdgo、rust-easyofd、java-ofdrw、 python-easyofd、@miconvert/ofd-to-pdfMIT 3 个实例 / 3 个库 python-ofdreader、wanglrebe/pdf2ofd、Hufe921/jsOFD无 1 个实例 / 1 个库 ⚠️ jsyzdej/ofd2pdf⚠️ ofd-libraries.md 中"无"只表示该库未声明许可证。按通行做法,未声明即默认保留所有权利,不等于免费可用 —— 商用前必须法务确认或联系作者。(此为法律常识补充,非基准测试文档原文结论。)
七、上线前的六项自检
⚠️ 选型前先确认版本。本系列数据绑定特定版本(见 第 〇 节),go-ofdgo 曾在一次提交里修掉三个 PDF→OFD bug —— 榜单排名可能在你读这篇文章时就变了。第 0 项是版本,不是能力。
不管选谁,上线前跑完这六项:
□ 0. 已锁定库版本号,并记录在选型文档里□ 1. 用自己的真实文档跑通(不是 hello)□ 2. 复杂样本(intro 类 / 签章 / 发票)全部通过□ 3. 文本提取 > 0,且人工确认不是乱码□ 4. 像素门禁达标(建议 ≥98%,按业务调)□ 5. 体积在预算内(算 26 倍膨胀场景能否接受)□ 6. 许可证已法务确认再加两条面向生产的:
□ 7. 大页数(1000+)压测,实测单页耗时可接受□ 8. 失败有兜底:转换失败不能丢件,要进重试或人工队列八、一句话收束
选型的正确顺序: 1. 先问「要文本吗」 → 定路线,砍掉一半选项 2. 再问「能商用吗」 → 砍掉无许可证的 3. 再问「文档有多复杂」 → 定验收样本 4. 最后才看「谁最快」 → 在剩下的里选顺序反了,就会在"7 胜 0 负"上翻车。参考资料
ofd-benchmark/docs/ofd-to-pdf.md、 docs/pdf-to-ofd.md(全部数据)ofd-benchmark/docs/ofd-libraries.md(66 个库能力/许可证)