❝anydoc 是一个用 Rust 构建的高性能文档转 Markdown 库,它支持 Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF 共 14 种格式的转换,中位数转换时间不到 5 毫秒,并提供 Node.js、Python 和浏览器 WebAssembly 三种绑定,让你在自己熟悉的语言环境里直接调用它,不用学 Rust。
简单说,它就是一个"文档翻译官",能把各种办公文件瞬间变成 AI 能轻松读懂的纯文本格式。
打个比方:你手里有一份日报(Word)、一份季度汇报 PPT、一张财务 Excel 表格、一本电子书。你把它们全部扔给它,"嗖"一下,它们全部变成了同一份结构清晰的纯文字稿——所有标题、表格、图片说明、脚注都保留着,格式统一,排版干净,全世界任何阅读器都能直接看。
基准测试表现
anydoc 针对 100 篇涵盖 14 种格式的真实文档与 6 款转换工具进行了盲评基准测试(由 Claude Sonnet 5 作为 LLM 裁判对照 LibreOffice 渲染的图像进行打分,总分 100):
格式覆盖最广:anydoc 覆盖了全部 14/14 种格式,是基准测试中唯一实现全格式覆盖的工具。 综合质量评分最高:anydoc 在 94 篇被实际评判的文档中,获得了 81 分的最高综合得分(其中完整性 87、结构 79、格式 78、清洁度 81),并在每个单项支持格式的 Like-for-Like 对比中均位列第一。 速度领先一个数量级:在 Ryzen 9 9950X3D 测试环境下,anydoc 的中位转换耗时仅为 4.4 毫秒,大幅领先于 Pandoc(102.1 ms)、MarkItDown(134.8 ms)和 Docling(513.6 ms)等工具。
要点
统一的解析与序列化架构:所有支持的文档格式在输入后,都会先被解析为统一的共享文档模型(Document),再通过同一个 Markdown 序列化器输出为 GitHub-Flavored Markdown (GFM)。这种设计使得转义、表格、标题锚点和脚注等在各格式间的输出表现完全一致,且针对排版或转义缺陷的修复只需在序列化器中修改一次,即可自动应用到所有格式(例如对
.docx的表格转义修复会自动应用到.rtf和.odt等其他所有格式)。本地 PDF 转换及边界:内置对文本型 PDF 的本地解析支持,通过
pdf-inspector直接转换为 Markdown,无需外部 OCR 服务;不过,对于纯图片或扫描版的 PDF,由于 anydoc 不具备本地 OCR 功能,转换会触发Unsupported错误。基于内容签名检测格式(而非依赖扩展名),即使文件被错误命名也能正确识别;CSV 因无签名需显式指定格式。
结构与嵌入资源完整保留:支持转换包含标题锚点、粗体/斜体/删除线、代码块、链接与交叉引用、带合并单元格和表头的表格、嵌套/任务列表(保留源编号)、脚注、尾端注以及幻灯片演讲者备注在内的完整结构。图片等嵌入资源在 Markdown 中呈现为 alt 文本,而其原始字节(带有媒体类型标签)则完整保留在文档模型中供提取。
无阻塞的多语言绑定:
Node.js 绑定:在 libuv 线程池中异步运行,不阻塞事件循环。 Python 绑定:在执行时释放全局解释器锁(GIL),使其他 Python 线程可并行运行。 浏览器 WASM:通过 @firecrawl/anydoc-wasm完全在本地浏览器运行,文件不上传服务器。以 Agent Skill 形式发布,Claude Code、Codex、Cursor 等智能体可通过
npx skills add firecrawl/anydoc直接调用。
安装与使用
CLI(推荐快速体验):
npx @firecrawl/anydoc report.docx # 输出到标准输出npx @firecrawl/anydoc slides.pptx -o slides.md # 输出到文件npm install -g @firecrawl/anydoc # 全局安装,获得 anydoc 命令Node.js:
npm install @firecrawl/anydocimport { toMarkdown, toMarkdownBytes } from'@firecrawl/anydoc';const md = await toMarkdown('report.docx');const md = await toMarkdownBytes(bytes, 'csv'); // 无签名格式需指定Python:
pip install firecrawl-anydocimport anydocmarkdown = anydoc.to_markdown("report.docx")markdown = anydoc.to_markdown_bytes(data, "csv")Rust:
# Cargo.tomlanydoc = "0.1"let markdown = anydoc::to_markdown("report.docx")?;浏览器 (WASM):
npm install @firecrawl/anydoc-wasmimport init, { toMarkdownBytes } from'@firecrawl/anydoc-wasm';await init();const md = toMarkdownBytes(bytes);项目由 Firecrawl 开发,采用 MIT License,当前 11.6k Stars。
❝项目地址:https://github.com/firecrawl/anydoc
夜雨聆风