当前位置: 首页 > news >正文

【office2pdf】office2pdf - 产品需求文档 (PRD.md)

1. 概述

office2pdf是一个库和命令行工具,使用纯 Rust 将 DOCX、XLSX 和 PPTX 文件转换为 PDF。
它无需外部运行时(LibreOffice、Chromium、Docker)即可独立运行,使用 Typst 引擎作为布局/PDF 后端。

核心价值

  • 零依赖:无需外部二进制文件/服务,作为单个可执行文件运行
  • 高质量输出:以 95% 的保真度再现原始文档的布局/样式
  • 库优先:可嵌入到其他 Rust 项目中,CLI 只是一个轻量封装

2. 目标用户

用户使用场景
后端开发人员服务端文档 → PDF 转换(报告、发票、打印输出)
DevOps/基础设施无需 LibreOffice/Docker 的轻量级转换流水线
CLI 用户从终端快速批量转换
Rust 开发人员作为 crate 嵌入到项目中

3. 功能需求

3.1 输入格式

DOCX (Word)
优先级功能描述
P0文本段落、换行、分页
P0行内格式粗体、斜体、下划线、删除线、字体、字号、颜色
P0段落格式对齐(左/右/居中/两端对齐)、缩进、行距
P0表格基本表格、单元格合并、边框、背景色
P0图片内嵌图片、基本尺寸调整
P1列表编号列表、项目符号列表(多级)
P1页眉/页脚文本、页码
P1页面设置纸张大小、页边距、方向(纵向/横向)
P1样式应用文档样式表(标题 1~6 等)
P2目录目录渲染
P2超链接PDF 中的可点击链接
P2脚注/尾注脚注、尾注渲染
P3文字环绕图片周围的文字流动
P3公式OMML 数学公式
P3图表内嵌图表渲染
PPTX (PowerPoint)
优先级功能描述
P0幻灯片 → 页面1 张幻灯片 = 1 页的映射
P0文本框位置、大小、文本内容、格式
P0基本形状矩形、圆形、线条等
P0图片幻灯片内的图片放置
P1背景纯色、渐变、图片背景
P1母版/版式幻灯片母版 → 版式 → 幻灯片继承链
P1主题主题颜色、主题字体解析
P1表格幻灯片内的表格渲染
P2组合形状组合形状的处理
P2形状样式阴影、反射、旋转、透明度
P3SmartArtSmartArt 图形
P3图表内嵌图表
XLSX (Excel)
优先级功能描述
P0单元格数据文本、数字、日期值的输出
P0基本表格布局行/列 → PDF 表格转换
P0单元格合并合并单元格的处理
P1单元格格式字体、颜色、背景色、边框
P1列宽/行高反映原始尺寸
P1数字格式货币、百分比、日期格式字符串
P1工作表选择转换特定工作表或所有工作表
P2打印区域反映配置的打印区域
P2页眉/页脚工作表的页眉/页脚
P2分页符手动分页符的处理
P3条件格式条件格式渲染
P3图表内嵌图表渲染

3.2 输出

功能描述
PDF 输出生成有效的 PDF 文件
PDF 版本默认 PDF 1.7,可选 PDF/A
字体嵌入在 PDF 中嵌入使用的字体
元数据标题、作者、创建日期等

4. 非功能需求

类别需求
性能10 页文档 < 1 秒,100 页 < 5 秒
内存处理 100 页文档时 < 500MB
二进制大小CLI < 50MB(包含字体)
平台Windows、macOS、Linux
错误处理跳过无法解析的元素并发出警告,继续整体转换
字体回退系统字体发现 + 内置默认字体

5. 架构

5.1 转换流水线

输入文件 (.docx/.pptx/.xlsx) │ ▼ [1. 解析器] ─── docx-rs / ppt-rs / umya-spreadsheet │ ▼ [2. IR (中间表示)] ← 格式无关的文档模型 │ ▼ [3. Typst 代码生成] ─── IR → Typst 标记生成 │ ▼ [4. Typst 编译] ─── typst-as-lib / typst crate │ ▼ [5. PDF 导出] ─── typst-pdf │ ▼ output.pdf

5.2 IR (中间表示) 设计

所有输入格式在输出到 Typst 之前都转换为统一的 IR:

pubstructDocument{pubmetadata:Metadata,pubpages:Vec<Page>,pubstyles:StyleSheet,}pubenumPage{Flow(FlowPage),// DOCX:流式文本页面Fixed(FixedPage),// PPTX:固定坐标页面Table(TablePage),// XLSX:基于表格的页面}pubstructFlowPage{pubsize:PageSize,pubmargins:Margins,pubheader:Option<HeaderFooter>,pubfooter:Option<HeaderFooter>,pubcontent:Vec<Block>,}pubenumBlock{Paragraph(Paragraph),Table(Table),Image(Image),PageBreak,List(List),}

5.3 项目结构

office2pdf/ ├── Cargo.toml # 工作区根目录 ├── crates/ │ ├── office2pdf/ # 库 crate │ │ ├── Cargo.toml │ │ └── src/ │ │ ├── lib.rs # 公共 API │ │ ├── error.rs # thiserror 错误类型 │ │ ├── ir/ # 中间表示 │ │ │ ├── mod.rs │ │ │ ├── document.rs # Document, Page, Block 等 │ │ │ ├── style.rs # 样式/格式模型 │ │ │ └── elements.rs # Paragraph, Table, Image 等 │ │ ├── parser/ # 输入格式解析器 │ │ │ ├── mod.rs # Parser trait │ │ │ ├── docx.rs # DOCX → IR │ │ │ ├── pptx.rs # PPTX → IR │ │ │ └── xlsx.rs # XLSX → IR │ │ ├── render/ # IR → PDF 渲染 │ │ │ ├── mod.rs │ │ │ ├── typst_gen.rs # IR → Typst 标记生成 │ │ │ └── pdf.rs # Typst 编译 + PDF 输出 │ │ └── config.rs # 转换选项 │ └── office2pdf-cli/ # CLI crate │ ├── Cargo.toml │ └── src/ │ └── main.rs # 基于 clap 的 CLI ├── tests/ # 集成测试 │ ├── fixtures/ # 测试文档文件 │ └── integration_tests.rs └── fonts/ # 内置默认字体

5.4 关键依赖

Crate用途备注
typst布局引擎typst-as-lib
typst-pdfPDF 输出
typst-kit字体发现
docx-rsDOCX 解析v0.4.19,活跃维护中
umya-spreadsheetXLSX 解析(含格式)支持样式/格式提取
ppt-rsPPTX 解析python-pptx 的 Rust 移植版
clapCLI 参数解析v4 derive
thiserror库错误
anyhowCLI 错误

6. 公共 API(库)

useoffice2pdf::{Document,ConvertOptions,Format};// 简单用法letpdf_bytes=office2pdf::convert("input.docx")?;std::fs::write("output.pdf",pdf_bytes)?;// 带选项letoptions=ConvertOptions::builder().paper_size(PaperSize::A4).font_paths(vec!["./fonts"]).pdf_standard(PdfStandard::PdfA2b).build();letpdf_bytes=office2pdf::convert_with_options("input.xlsx",&options)?;// 从字节转换letdocx_bytes=std::fs::read("input.docx")?;letpdf_bytes=office2pdf::convert_bytes(&docx_bytes,Format::Docx,&options)?;// 仅转换特定工作表/幻灯片letoptions=ConvertOptions::builder().sheet_names(vec!["Sheet1"])// XLSX:仅特定工作表.slide_range(1..=5)// PPTX:仅幻灯片 1-5.build();

7. CLI 接口

# 基本转换office2pdf input.docx# → input.pdfoffice2pdf input.pptx-ooutput.pdf# 指定输出路径# 选项office2pdf input.xlsx--sheets"Sheet1,Sheet2"# 仅特定工作表office2pdf input.pptx--slides1-5# 仅特定幻灯片office2pdf input.docx--papera4--landscape# 纸张设置office2pdf input.docx --font-path ./fonts# 字体路径# 批量转换office2pdf *.docx--outdir./pdfs/# 批量转换多个文件# 信息office2pdf--versionoffice2pdf--help

8. 实施阶段

阶段 1:MVP(基础文本 + 图片)

  • 项目结构搭建(工作区、CI)
  • IR 定义
  • DOCX P0 功能 → IR → Typst → PDF
  • PPTX P0 功能 → IR → Typst → PDF
  • XLSX P0 功能 → IR → Typst → PDF
  • 基础 CLI 功能

阶段 2:格式 + 样式

  • 所有 P1 功能实现
  • 字体嵌入/回退
  • 增强错误处理

阶段 3:高级功能

  • P2 功能实现
  • PDF/A 支持
  • 性能优化
  • 批量转换

阶段 4:完善

  • P3 功能(在可行范围内)
  • 边缘情况处理
  • 文档、示例、crates.io 发布

9. 验证方法

方法描述
Golden 测试测试文档 → PDF → 截图对比
往返测试转换已知文档并通过文本提取验证
手动对比MS Office PDF 输出与 office2pdf 输出对比
CI每次提交时自动转换测试文档集

10. 风险

风险影响缓解措施
OOXML 规范复杂性解析 crate 可能不支持所有元素跳过不支持的元素 + 警告日志
Typst IR 转换限制某些布局可能无法在 Typst 中表达在 Typst 能力范围内进行最佳近似
字体兼容性原始字体可能不可用系统字体发现 + 回退字体映射
解析 crate 维护依赖 crate 可能被弃用准备分支,考虑为核心解析器自行实现
http://www.jsqmd.com/news/564127/

相关文章:

  • 手机也能玩转Llama3.1!用Cpolar穿透实现移动端访问LobeChat的5个技巧
  • 无需安装即可畅享B站视频:downkyi绿色版全方位使用指南
  • RTX 4090D专属优化!Wan2.2-I2V-A14B私有部署镜像,小白也能快速上手
  • 使用CMake与vcpkg简化C/C++项目依赖管理
  • 2026AI大淘汰前夜:3个自动化技能让你年薪翻倍,成为筛不掉的职场金粉!
  • VideoAgentTrek-ScreenFilter视频智能过滤实战:基于卷积神经网络的实时画面处理
  • RealRestorer:AI修复真实图像的终极利器
  • Windows Subsystem for Android实战指南:从环境配置到核心功能落地的系统方案
  • 代理IP:按流量还是按IP/时长计费更划算?
  • Flutter项目卡在‘assembleDebug’?Gradle配置优化全攻略
  • Phi-4-Reasoning-Vision入门必看:双卡4090环境配置与THINK/NOTHINK模式详解
  • OWL ADVENTURE系统清理与维护:释放C盘空间与优化存储
  • 产品好却卖不动?90%的小团队都死在这一步
  • 微信小程序集成AI能力:调用LFM2.5-1.2B-Thinking-GGUF实现智能聊天与内容生成
  • Qwen3-ASR-0.6B部署教程:腾讯云TI-ONE平台GPU训练/推理一体化部署流程
  • RWKV7-1.5B-g1a效果展示:‘请用一句中文介绍你自己’真实响应
  • AI头像生成器镜像优化:Qwen3-32B 4-bit量化后8GB显存稳定运行实录
  • 突破Windows XP/2003兼容性壁垒:One-Core-API-Source革新方案解析
  • OFA视觉问答模型镜像免配置:3条命令启动,告别pip install地狱
  • OFA模型在零售行业的视觉问答应用案例
  • 【Linux的以太网驱动的收发流程比较】
  • 新手也能上手!盘点2026年倍受青睐的AI论文软件
  • Kandinsky-5.0-I2V-Lite-5s图生视频参数调优:引导强度5.0为何是默认最优值?
  • Mirage Flow 与 .NET 生态融合:开发跨平台智能桌面应用
  • GLM-4.1V-9B-Base学术研究辅助:文献综述与实验方案设计
  • Palo Alto PAN-OS 12.1.5 VM-Series for ESXi, KVM - 基于机器学习的下一代防火墙操作系统
  • 【airsimunity】添加人物与行走动画
  • (转)mybatis拦截器
  • 2019~2026年更新大众点评数据,商家店铺,电话,评分,营业时间,名称地址经纬度,消费价格,支持外卖,收录时间等字段~不指定年份的话,默认报价是2026年。默认发2026年的
  • C++ 中this的秘密