pdfxml - PDF XML 注释导出工具
将 XFDF/XML 格式的 PDF 注释导出为 PDF 文件的 Rust 工具,也可以作为 Rust SDK / library 直接调用。
✨ 功能特性
-
📝 支持 XFDF/XML 批注解析与转换:当前覆盖大部分常见批注类型,详细范围见 ANNOTATION_SUPPORT.md
-
🎨 多种注释类型:
- 文本注释(Text/便签)
- 高亮(Highlight)、下划线(Underline)、删除线(StrikeOut)
- 自由文本(FreeText)
- 方形(Square)、圆形(Circle)
- 线条(Line)、多边形(Polygon)
- 墨迹/手绘(Ink)
- 图章(Stamp)
- 弹出窗口(Popup)
-
🔧 两种导出模式:
- 创建新 PDF:仅包含注释信息
- 合并到现有 PDF:将注释添加到已有文档
-
⚡ 高性能:纯 Rust 实现,内存安全,速度快
-
📋 批注支持清单:详见 ANNOTATION_SUPPORT.md
📖 XFDF 格式简介
XFDF (XML Forms Data Format) 是 Adobe 定义的一种 XML 格式,用于独立存储 PDF 文档中的表单数据和注释。它是 FDF 的 XML 版本。
基本结构示例
注释内容...
支持的注释类型
| XML 元素 | PDF 子类型 | 说明 |
|---|---|---|
<text> |
Text | 文本便签 |
<highlight> |
Highlight | 高亮文本 |
<underline> |
Underline | 下划线 |
<strikeout> |
StrikeOut | 删除线 |
<freetext> |
FreeText | 自由文本框 |
<square> |
Square | 矩形标记 |
<circle> |
Circle | 圆形/椭圆标记 |
<line> |
Line | 箭头/线条 |
<polygon> |
Polygon | 多边形区域 |
<ink> |
Ink | 手绘墨迹 |
<stamp> |
Stamp | 预设图章 |
📖 文档导航
- 想直接在终端使用:看下面的 快速开始
- 想把它当 Rust 库调用:看 SDK_GUIDE.md
- 想快速理解公开 API:优先看
src/lib.rs
🚀 快速开始
安装
从源码构建 CLI
# 克隆项目
# 编译 CLI
通过 Git 直接安装 CLI
在 Rust 项目里通过 Git 依赖库
[]
= { = "https://github.com/hearsay316/pdfXml.git" }
如果你是从仓库源码直接运行 workspace 内的 CLI,可以使用:
使用方法
# 基本用法:创建新 PDF
# 指定目标 PDF(合并注释到现有文档)
# 从 PDF 导出标准 XFDF
# 详细输出模式
命令行参数
| 参数 | 缩写 | 必填 | 说明 |
|---|---|---|---|
--input |
-i |
✓ | 输入文件路径(XFDF 或 PDF) |
--output |
-o |
输出文件路径 | |
--target-pdf |
-t |
目标 PDF 文件路径(仅 XFDF -> PDF 时可选) | |
--from-pdf |
从 PDF 导出 XFDF | ||
--verbose |
-v |
详细输出模式 |
当前更推荐通过 Git 安装或 Git 依赖使用本项目。若后续发布到 crates.io,发布顺序将是:先
pdfxml,再pdfxml-cli。
📁 项目结构
pdfxml/
├── Cargo.toml # 根库 crate + workspace 配置
├── README.md # 项目说明
├── cli/
│ ├── Cargo.toml # CLI crate 配置
│ └── src/
│ └── main.rs # CLI 薄壳入口
├── src/
│ ├── lib.rs # 对外 SDK / library 入口
│ ├── xfdf.rs # XFDF/XML 解析模块
│ ├── pdf.rs # PDF 生成模块
│ ├── annotation.rs # 注释数据结构定义
│ └── error.rs # 错误类型定义
├── examples/
│ ├── sample.xfdf # 完整示例文件
│ └── minimal.xfdf # 最小示例文件
└── tests/
└── integration_test.rs # 面向公开 API 的集成测试
💡 使用示例
示例 1:从 XFDF 创建新 PDF
示例 2:合并注释到现有 PDF
假设你有一个 PDF 和一个包含注释的 XFDF 文件:
示例 3:从 PDF 导出 XFDF
示例 4:在代码中作为库调用
use ;
use Path;
示例 5:使用顶层 SDK 包装函数
use ;
示例 6:从 PDF 读取注释并转回 XFDF
use ;
🧪 运行测试
# 运行所有测试
# 显示详细输出
# 仅运行库测试
# 仅运行 CLI crate 检查/测试
📌 图形注释显式 AP 计划
目前 square 已经补了显式外观流(AP, Appearance Stream),也就是不仅写入“这是一个矩形注释”的属性,还会把矩形本身直接画进 PDF。这样做的效果是:
- 不同阅读器显示更一致
- 降低“对象存在但看不见”的概率
- 导出的结果更接近标注软件原始效果
下一步计划把同样的方式扩展到这些图形注释:
circlelinepolygonpolyline
通俗理解:
- 现在很多图形注释只是告诉阅读器“这里有个圆/线/多边形,请你自己画”
- 显式 AP 是把“已经画好的外观”直接放进 PDF,让阅读器直接显示
计划中的预期行为
circle:生成显式 AP,稳定显示圆形/椭圆边框,保留线宽、边框色、填充色line:生成显式 AP,稳定显示线段,后续可继续细化端点样式(箭头等)polygon:生成显式 AP,按顶点绘制封闭多边形polyline:生成显式 AP,按顶点绘制非封闭折线
当前状态
这一轮先不改实现,只先补:
- 文档说明
- 测试用例骨架
等你先提交当前这版代码后,再继续改 circle / line / polygon / polyline 的显式 AP 实现。
🛠️ 技术实现
核心依赖库
| 库 | 用途 | 版本 |
|---|---|---|
| quick-xml | 高性能 XML 解析 | ^0.36 |
| lopdf | PDF 生成和操作 | ^0.35 |
| clap | 命令行参数解析 | ^4.5 |
| chrono | 日期时间处理 | ^0.4 |
架构设计
XFDF/XML 文件
│
▼
┌─────────────┐ ┌─────────────────┐
│ xfdf.rs │───▶│ annotation.rs │
│ XML 解析器 │ │ 数据结构定义 │
└─────────────┘ └─────────────────┘
│
▼
┌─────────────┐
│ pdf.rs │
│ PDF 生成器 │
└─────────────┘
│
▼
PDF 文件输出
📋 待办功能
- 支持 FDF(非 XML)格式
- 支持富文本内容(HTML/XHTML)
- 支持附件注释
- 支持声音注释
- 支持链接注释
- 支持表单字段填充
- GUI 界面
- WebAssembly 编译支持
🤝 贡献
欢迎提交 Issue 和 Pull Request!
- Fork 本仓库
- 创建特性分支 (
git checkout -b feature/AmazingFeature) - 提交更改 (
git commit -m 'Add some AmazingFeature') - 推送到分支 (
git push origin feature/AmazingFeature) - 开启 Pull Request
📄 许可证
本项目采用 MIT 许可证 - 查看 LICENSE 文件了解详情。
🙏 致谢
- Adobe XFDF 规范
- lopdf 库的维护者
- Rust 社区
Made with ❤️ using Rust