@opensourcelab9:致那些想将文档喂给AI的人们—— 一款工具已发布,可将Word、PowerPoint、Excel、PDF和EPUB……
摘要
一款名为anydoc的开源Rust工具已发布,可将Word、PowerPoint、Excel、PDF及其他文档格式转换为Markdown,供AI和大语言模型使用,并提供Node.js和Python绑定。
查看缓存全文
缓存时间: 2026/08/30 22:22
面向需要将文档输入AI的用户,现已发布一款可一次性将Word、PowerPoint、Excel、PDF和EPUB文件转换为Markdown的工具。这款名为anydoc的工具已获得19,000颗星标:
- 基于Rust构建,可批量处理大量文件
- 可直接从Node.js和Python调用
- 采用MIT许可证,可嵌入内部工具
繁琐的手动复制粘贴准备工作,现在只需一条命令即可完成。
开源时代已到来——
firecrawl/anydoc
源代码:https://github.com/firecrawl/anydoc
anydoc
Crates.io (https://crates.io/crates/anydoc)
npm (https://www.npmjs.com/package/@firecrawl/anydoc)
PyPI (https://pypi.org/project/firecrawl-anydoc/)
MIT许可证
skills.sh (https://skills.sh/firecrawl/anydoc)
快速Rust库,可将文档(Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV和PDF)转换为干净的GitHub风格Markdown。提供Node.js、Python和浏览器(WebAssembly)的绑定支持。
由Firecrawl (https://firecrawl.dev) 构建,可将任何办公文档转换为LLM就绪的Markdown格式,转换时间在个位数毫秒内完成,无论输入格式如何都能输出一致结果。该工具驱动了Firecrawl Parse (https://firecrawl.dev/parse),如果您不想自行运行,托管API可提供相同的转换功能,并针对anydoc无法自动识别的扫描页面提供OCR模型支持。
在浏览器中尝试 (https://firecrawl.github.io/anydoc/):演示页面以WebAssembly方式运行库,文件在本地转换,永远不会离开您的设备。
快速开始
智能体技能
anydoc以智能体技能 (https://agentskills.io) 形式提供,使您的智能体能够读取遇到的任何文档:
npx skills add firecrawl/anydoc
该技能教授智能体如何使用anydoc CLI转换文档。兼容Claude Code (https://claude.ai/code)、Codex (https://openai.com/codex/)、Cursor (https://cursor.com)、OpenCode (https://opencode.ai)及其他兼容的智能体 (https://agentskills.io/clients)。
命令行界面
npx @firecrawl/anydoc report.docx # 转换为Markdown并输出到标准输出
npx @firecrawl/anydoc slides.pptx -o slides.md # 或输出到文件
npx @firecrawl/anydoc - --format csv < data.csv # 从标准输入读取
npx @firecrawl/anydoc scan.pdf --ocr hosted # 通过Firecrawl Parse处理扫描页面
首次运行时npx会为您的平台下载预编译二进制文件。要永久使用anydoc命令,可通过npm install -g @firecrawl/anydoc进行全局安装。运行anydoc --help查看所有选项。
Node.js
npm install @firecrawl/anydoc
import { toDocument, toMarkdown, toMarkdownBytes } from '@firecrawl/anydoc';
// 从文件路径转换:
const markdown = await toMarkdown('report.docx');
// 启用OCR功能:
const markdown = await toMarkdown('report.docx', { ocr: 'hosted' });
// 从字节数据转换(自动检测格式):
const fromBytes = await toMarkdownBytes(bytes);
// 或指定格式(CSV等无格式标识的文件需要):
const fromCsv = await toMarkdownBytes(bytes, 'csv');
// 或获取文档模型(包含嵌入式资源):
const document = await toDocument(bytes);
完整API参考:node/README.md
Python
pip install firecrawl-anydoc
import anydoc
# 从文件路径转换:
markdown = anydoc.to_markdown("report.docx")
# 启用OCR功能:
markdown = anydoc.to_markdown("report.docx", ocr="hosted")
# 从字节数据转换(自动检测格式):
markdown = anydoc.to_markdown_bytes(data)
# 或指定格式(CSV等无格式标识的文件需要):
markdown = anydoc.to_markdown_bytes(data, "csv")
# 或获取文档模型(包含嵌入式资源):
document = anydoc.to_document(data)
完整API参考:python/README.md
浏览器(WebAssembly)
npm install @firecrawl/anydoc-wasm
import init, { toMarkdownBytes, toDocument } from '@firecrawl/anydoc-wasm';
await init();
// 从字节数据转换(自动检测格式):
const markdown = toMarkdownBytes(bytes);
// 或指定格式(CSV等无格式标识的文件需要):
const fromCsv = toMarkdownBytes(bytes, 'csv');
// 或获取文档模型(包含嵌入式资源):
const document = toDocument(bytes);
完整API参考:wasm/README.md
Rust
cargo add anydoc
// 从文件路径转换:
let markdown = anydoc::to_markdown("report.docx")?;
// 从字节数据转换(自动检测格式):
let markdown = anydoc::to_markdown_bytes(&bytes, None)?;
// 或指定格式(CSV等无格式标识的文件需要):
let markdown = anydoc::to_markdown_bytes(&bytes, anydoc::Format::Csv)?;
// 或获取文档模型(包含嵌入式资源):
let document = anydoc::to_document(&bytes, None)?;
OCR功能
anydoc可在本地读取文本型PDF,但不进行OCR处理,因此包含扫描或纯图像页面的PDF会返回NeedsOcr错误。启用此功能后,这些文档将发送至Firecrawl Parse (https://firecrawl.dev/parse) 进行OCR处理,并返回相同的Markdown格式。无需注册账户;设置FIRECRAWL_API_KEY可获得更高额度。
| 环境 | 启用方式 | 需配置的密钥(或默认使用FIRECRAWL_API_KEY) |
|---|---|---|
| 命令行界面 | anydoc scan.pdf --ocr hosted | --api-key <密钥> |
| Node.js | toMarkdown('scan.pdf', { ocr: 'hosted' }) | apiKey |
| Python | anydoc.to_markdown("scan.pdf", ocr="hosted") | api_key |
只有需要OCR处理的文档才会离开本机,且会发送整个文档(因为Parse不支持页面选择)。若Parse无法转换,Node.js会返回code: 'hosted'错误,Python则抛出HostedError。
--api-url、apiUrl和api_url可指向其他Parse部署实例(默认使用FIRECRAWL_API_URL)。
Rust版本没有ocr选项,且永远不会发起网络请求。
功能特性
- 统一输出格式:每种格式都解析为共享文档模型,并通过单一Markdown序列化器渲染,无论输入是2003年的
.doc还是昨天的.pptx,转义、表格、标题锚点和脚注的行为都保持一致。 - 完整文档结构:带锚点的标题、粗体/斜体/删除线、行内代码和代码块、链接和内部交叉引用、带原始编号的项目符号/编号/嵌套/任务列表、带合并单元格和标题行的表格、引用块、脚注和尾注,以及演讲者注释。
- 方程转LaTeX:Word和PowerPoint(OMML)、OpenDocument和EPUB(MathML)以及RTF方程都转换为GitHub风格数学格式:行内使用
$...$,独立区块使用$$。 - 嵌入式资源:图片和嵌入式对象在Markdown中显示为替代文本,原始字节保留在文档模型中并带有媒体类型标记。带外部URL的图片转换为普通Markdown图片。
- 基于内容的格式检测:从文件字节本身读取格式(PDF头、RTF开放组、OLE流名称、ZIP包mimetype),因此标记错误的文件仍能正确转换。
- 高性能:纯Rust实现,无机器学习模型,无外部服务。文档转换中位时间低于5毫秒。
- 不干扰的绑定库:Node.js转换在libuv线程池运行,永不阻塞事件循环;Python释放GIL以保持其他线程运行。TypeScript类型和Python存根随包提供。
- 内置PDF支持:文本型PDF通过pdf-inspector (https://github.com/firecrawl/pdf-inspector) 在本地转换,无需OCR服务。扫描页面可选择使用托管OCR。
- 智能体就绪:以智能体技能形式提供:只需一条
npx skills add firecrawl/anydoc命令,任何智能体都能读取办公文档。
支持格式
| 格式 | 扩展名 |
|---|---|
| Word | .doc, .docx, .docm |
| PowerPoint | .ppt, .pps, .pot, .pptx, .pptm, .ppsx, .ppsm |
| Excel | .xls, .xlsx, .xlsm, .xlsb |
| OpenDocument | .odt, .ods, .odp |
| RTF | .rtf |
| EPUB | .epub |
| CSV | .csv |
.pdf |
基准测试
anydoc与六款其他转换器在涵盖十四种格式的100份真实文档上进行对比测试。评分范围0-100分(越高越好);速度为单文档转换中位时间。
| 工具 | 支持格式数 | 中位毫秒 | 已评测文档数 | 综合得分 | 完整性 | 结构性 | 格式保留 | 整洁度 |
|---|---|---|---|---|---|---|---|---|
| anydoc | 14/14 | 4.4 | 94 | 81 | 87 | 79 | 78 | 81 |
| libreoffice | 12/14 | 1129.5 | 87 | 40 | 59 | 42 | 40 | 24 |
| unstructured | 8/14 | 572.9 | 58 | 63 | 76 | 59 | 51 | 63 |
| markitdown | 6/14 | 134.8 | 33 | 65 | 78 | 66 | 60 | 52 |
| pandoc | 5/14 | 102.1 | 34 | 56 | 74 | 57 | 56 | 38 |
| docling | 4/14 | 513.6 | 21 | 57 | 60 | 60 | 57 | 51 |
| mammoth | 1/14 | 52.5 | 8 | 70 | 84 | 71 | 75 | 51 |
按格式逐项对比:
| 格式 | anydoc | libreoffice | unstructured | markitdown | pandoc | docling | mammoth |
|---|---|---|---|---|---|---|---|
| doc | 87 | 57 | 67 | - | - | - | - |
| docm | 84 | 48 | - | - | - | - | - |
| docx | 88 | 56 | 53 | 71 | 68 | 71 | 70 |
| epub | 77 | - | 72 | 72 | 52 | - | - |
| odp | 86 | 23 | - | - | - | - | - |
| ods | 82 | 38 | - | - | - | - | - |
| odt | 80 | 51 | 68 | - | 60 | - | - |
| ppt | 80 | 26 | - | - | - | - | - |
| pptx | 74 | 24 | - | 66 | - | 52 | - |
| rtf | 88 | 53 | 46 | - | 45 | - | - |
| xls | 80 | 38 | 66 | 62 | - | - | - |
| xlsm | 76 | 32 | - | - | - | - | - |
| xlsx | 72 | 30 | 66 | 55 | - | 47 | - |
质量评分方式:LLM评判员(Claude Sonnet 5)将两款工具的输出与基准真相(文档前六页,由LibreOffice渲染为图像)进行盲评。每项输出从完整性、结构、格式和整洁度四个维度评分。每对评测会交换输出位置重复一次以消除位置偏差,总计482次判定。每个工具的score取其支持格式的平均分,因此语料库中某格式占比过高不会影响评分。这也意味着每行平均的格式集合不同(mammoth的69分仅基于docx,而anydoc的81分涵盖全部十四种格式),因此按格式对比表格才是公平参照。
速度测试使用Ryzen 9 9950X3D处理器(Windows 11,64GB DDR5-6400内存),测量单文档转换的中位时间。anydoc和Python库的计时排除了进程启动时间;命令行工具包含启动时间(因其实际使用方式如此)。测试框架位于bench/;语料库不可重新分发且未包含在代码库中。
最佳适用场景:接收混合格式办公文档,需要统一结构化Markdown输出的处理流程。在本次对比中,anydoc是唯一覆盖全部十四种格式的工具,在每个评测格式中得分最高,且转换速度比第二快工具高出一个数量级。
格式检测
根据文件内容读取格式,使用其规范指定的标记:PDF头、RTF开放组、OLE流名称、ZIP包mimetype和内容类型。CSV没有此类标记,因此需要通过扩展名或显式格式名称指定。
Format::from_bytes(&bytes); // 返回 Some(Format::Docx),无匹配时返回 None
Format::from_extension("pptm"); // 返回 Some(Format::Pptx)
Format::from_path(Path::new("report.odt")); // 返回 Some(Format::Odt)
Node.js(formatFromBytes等)和Python(anydoc.format_from_bytes等)提供相同功能。
错误处理
转换仅在文件无法生成完整Markdown时返回Err。ConvertError明确错误原因:
match anydoc::to_markdown(path) {
Ok(markdown) => Some(markdown),
// 以下情况无法生成文档,记录文件并继续处理下一个
Err(error @ (ConvertError::Encrypted | ConvertError::Unsupported(_) | ConvertError::NeedsOcr{..})) => {
unconverted.push((path, error));
None
}
Err(error) => return Err(error),
}
| 错误类型 | 含义 |
|---|---|
Unsupported | 未知格式或不支持转换的格式 |
NeedsOcr | PDF的扫描页或纯图像页,在pages列表中列出 |
Malformed | 结构损坏:无法提取有意义内容 |
Encrypted | 加密或密码保护文件 |
ResourceLimit | 超出安全限制(解压、嵌套深度、节点数量) |
MissingPart | 缺少生成有意义输出的必要部分 |
Io | 文件无法读取(仅出现在to_markdown错误中) |
Node.js和wasm通过error.code发布错误变体名称;Python为每个变体抛出对应的anydoc.ConvertError子类,文件不可读时抛出OSError。
anydoc在本地转换且不进行OCR,因此包含扫描页的PDF会返回NeedsOcr错误。在Node.js中使用ocr: 'hosted'、Python中使用ocr="hosted"或命令行界面使用--ocr hosted可启用该功能,将文档发送至Firecrawl Parse (https://firecrawl.dev/parse) 处理。无需注册账户;设置FIRECRAWL_API_KEY可获得更高额度。
工作原理
文档字节流
│
├─► 格式检测 → 基于内容标记(非扩展名)
│
├─► 格式解析器 → 每种格式对应独立解析器(doc、docx、ppt、pptx、xls、
│ xlsx、odt/ods/odp、rtf、epub、csv)
│ │
│ └─► 文档对象 → 共享模型:块级元素、行内元素、表格、
│ 脚注、资源
│ │
│ └─► GFM序列化器 → Markdown
│
└─► PDF → pdf-inspector → 直接生成Markdown
由于所有格式都通过相同的文档模型和序列化器处理,输出问题只需修复一次。docx的表格转义修复会自动应用于rtf、odt等所有格式。
开发
cargo test
cd node && npm install && npm run build && npm test
cd python && pip install maturin && maturin develop && python -m unittest discover -s tests
wasm-pack build wasm --release --target web --scope firecrawl && node --test wasm/test.mjs
# 详见 wasm/README.md
tests/fixtures/下的提交文件进行快照测试,tests/robustness.rs对每个文件进行变异测试,fuzz/包含每种格式的cargo-fuzz目标。性能和质量基准测试位于bench/。
发布版本使用v标签,通过.github/workflows/release.yml发布crate、npm包和PyPI轮子文件。版本号在三处同步更新:
Cargo.toml:crate版本node/package.json:npm包版本python/Cargo.toml:轮子文件版本(python/pyproject.toml读取该版本)
许可证
相似文章
@MoureDev:这个库可以将 Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF 文档转换为 Markdown!关键…
一个用 Rust 编写的库,可将 Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF 文档转换为 Markdown,可通过 npm、Python 和 CLI 使用,并强调其对 LLM 的实用性。
@GitHub_Daily: 给大模型喂文档,Word、PPT、Excel 格式都不一样,转出来的 Markdown 质量也参差不齐。 Firecrawl 团队用 Rust 写了 anydoc,支持 14 种办公格式转 Markdown,转换速度中位数不到 5 毫秒,…
Firecrawl 团队用 Rust 开发了 anydoc,一个可将 Word、PPT、Excel 等 14 种办公格式快速转换为统一 Markdown 的开源库,中位转换速度不到 5 毫秒,支持 Node.js、Python 和浏览器(WASM)使用。
@akshay_pachaar: 将任何PDF、图像、DOCX和PPTX转换为干净的markdown。解析单个PDF很简单。解析数百万个PDF才变得棘手。
Datalab发布了Marker v2,这是一个开源的文档解析管道,可以高效地将PDF、图像、DOCX和PPTX文件转换为markdown,支持超过90种语言,并在GPU上表现出高性能。
@HowToPrompt__: 有人开源了一个工具,每秒可将PDF转换为Markdown,速度达122页。→ PDF、DOCX、PPTX、XLSX、EPUB、图像…
一个开源工具可将PDF、DOCX、PPTX、XLSX、EPUB及图像转换为Markdown,速度达122页/秒,支持表格、公式和表单,可在GPU、CPU或Mac上运行。
@mdancho84: 将任何文档转换为LLM就绪的数据!微软发布了MarkItDown,一个轻量级Python库,可将任何文档…
微软发布了MarkItDown,一个开源的Python库,可将任何文档转换为Markdown,以便与LLM配合使用。