Computer之Tool:firecrawl/anydoc(Markdown)的简介、安装和使用方法、案例应用之详细攻略
目录
[CLI 安装与运行](#CLI 安装与运行)
[Python 安装](#Python 安装)
[Rust 安装](#Rust 安装)
[WebAssembly 安装](#WebAssembly 安装)
[案例一:使用 CLI 将 Word 文档转换为 Markdown](#案例一:使用 CLI 将 Word 文档转换为 Markdown)
[案例二:Node.js 中按内容识别格式并导出资源](#案例二:Node.js 中按内容识别格式并导出资源)
[案例三:Python 批量转换入口的实现方式](#案例三:Python 批量转换入口的实现方式)
[案例四:Rust 中实现完整的文档转换命令](#案例四:Rust 中实现完整的文档转换命令)
[案例五:在浏览器中通过 WebAssembly 转换文档](#案例五:在浏览器中通过 WebAssembly 转换文档)
anydoc的简介
anydoc 是 Firecrawl 开源的一个基于 Rust 实现的文档转换库,用于将 Word、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF 转换为干净的 GitHub-Flavored Markdown(GFM)。项目同时提供 Node.js、Python 以及 WebAssembly 绑定,并支持通过 CLI 直接执行文档转换。仓库将其定位为面向 LLM 的 Markdown 转换工具,强调不同输入格式经过转换后能够得到一致的 Markdown 输出。
anydoc 的核心设计是让不同文档格式先分别解析为统一的文档模型,再由统一的 GFM 序列化器生成 Markdown;PDF 则通过 pdf-inspector 在本地直接转换。统一模型包含块、行内内容、表格、脚注和资源等结构,因此标题、表格、列表、脚注等结构能够按照同一套规则输出。项目还支持根据文件内容进行格式识别,而不是单纯依赖文件扩展名;CSV 因为没有相应的内容标记,则使用扩展名或显式指定的格式进行识别。
从仓库给出的基准测试来看,anydoc 在 100 份真实文档、14 种格式的测试中覆盖了全部 14 种格式,记录的中位转换时间为 4.4ms,综合评分为 81;仓库同时说明,其测试中的质量评分涵盖完整性、结构、格式和整洁度。项目还提供 Agent Skill,可通过 npx skills add firecrawl/anydoc 使用 anydoc CLI,使兼容的 Agent 能够转换其遇到的文档。
1 、特点
|----------------|----------------------------------------------------------------------------------------------------------------------|
| 特点 | 详细说明 |
| 多格式统一转换 | 支持 Word(.doc、.docx、.docm)、PowerPoint、Excel、OpenDocument、RTF、EPUB、CSV 和 PDF 等格式,并统一输出 GitHub-Flavored Markdown。 |
| 统一文档模型 | 不同格式先进入共享的 Document 模型,再交由统一 Markdown 序列化器处理,使不同输入格式在转义、表格、标题锚点和脚注等方面遵循相同输出规则。 |
| 文档结构保留 | 支持标题及锚点、粗体、斜体、删除线、行内代码、代码块、链接、内部交叉引用、项目符号列表、编号列表、嵌套列表、任务列表、表格、引用、脚注、尾注和演讲者备注等结构。 |
| 数学公式转换 | Word 和 PowerPoint 中的 OMML、OpenDocument 与 EPUB 中的 MathML,以及 RTF 公式,可转换为 GitHub-Flavored Math 的 ... 行内公式和 $$ 块级公式形式。 |
| 嵌入资源处理 | Markdown 中无法直接嵌入字节数据,因此嵌入图片和对象会以替代文本形式呈现,而原始字节继续保留在文档模型的 assets 中,并带有媒体类型信息;具有外部 URL 的图片则按普通 Markdown 图片处理。 |
| 内容驱动的格式识别 | 项目根据文件内容中的格式标记进行检测,例如 PDF 文件头、RTF 开始分组、OLE 流名称以及 ZIP 包中的 MIME 类型和内容类型;因此文件扩展名与实际内容不一致时仍可进行识别。CSV 是例外,需要通过扩展名或显式格式指定。 |
| Rust 原生实现 | 仓库将 anydoc 描述为纯 Rust 实现,不使用 ML 模型或外部服务;README 给出的中位转换时间低于 5ms。 |
| 多语言绑定 | 提供 Node.js、Python 和 WebAssembly 绑定;Node.js 转换运行于 libuv 线程池,Python 转换会释放 GIL,同时随包提供 TypeScript 类型和 Python 类型存根。 |
| PDF 本地支持 | 文本型 PDF 可通过仓库集成的 pdf-inspector 在本地处理,无需 OCR 服务;仓库同时明确指出,单纯图片型 PDF 属于不能转换的情况。 |
| Agent Skill | 仓库自带 Agent Skill,通过 npx skills add firecrawl/anydoc 安装后,可让兼容的 Agent 借助 anydoc CLI 读取和转换文档。 |
| WebAssembly 支持 | 提供 @firecrawl/anydoc-wasm,API 与 Rust 库相对应,但由于 WASM 没有文件系统,因此转换从字节开始;仓库还提供浏览器演示页面。 |
| 基准测试表现 | 仓库使用 100 份真实文档、14 种格式进行测试,anydoc 覆盖 14/14 格式,中位时间 4.4ms,综合评分 81。 |
anydoc的安装和使用方法
1、安装
CLI 安装与运行
仓库提供了无需预先安装全局命令的 CLI 用法。首次使用 npx @firecrawl/anydoc 时,会下载当前平台对应的预构建二进制;需要长期使用 anydoc 命令时,可以进行全局安装。
npx @firecrawl/anydoc report.docx
npx @firecrawl/anydoc slides.pptx -o slides.md
npx @firecrawl/anydoc - --format csv < data.csv
长期安装:
npm install -g @firecrawl/anydoc
安装后可以使用:
anydoc --help
查看 CLI 的完整参数。
Node.js 安装
Node.js 版本通过 npm 安装:
npm install @firecrawl/anydoc
仓库同时提供从文件路径、字节数据以及显式格式指定开始转换的 API。
Python 安装
Python 版本通过 pip 安装:
pip install firecrawl-anydoc
安装包名称为 firecrawl-anydoc,代码中使用 anydoc 导入。
Rust 安装
Rust 项目可以直接加入依赖:
cargo add anydoc
仓库给出的 Rust API 同样支持从文件路径、字节数据以及显式 Csv 格式开始转换。
WebAssembly 安装
浏览器/WASM 版本使用:
npm install @firecrawl/anydoc-wasm
仓库说明该包通过 wasm-pack --target web 构建,可用于普通 <script type="module">,也支持能够处理 new URL(..., import.meta.url) 资源模式的打包器。
2、使用方法
Node.js
Node.js 的基本调用方式是直接将文件路径交给 toMarkdown:
import { toMarkdown } from '@firecrawl/anydoc';
const markdown = await toMarkdown('report.docx');
也可以从字节数据开始:
const markdown = await toMarkdownBytes(bytes);
对于 CSV 这类缺少内容签名的格式,可以显式传入格式:
const markdown = await toMarkdownBytes(bytes, 'csv');
还可以停止在文档模型阶段,通过 toDocument 获取包含嵌入资源的数据结构。
Python
Python 版本对应的基本调用方式为:
import anydoc
markdown = anydoc.to_markdown("report.docx")
从字节数据转换时:
markdown = anydoc.to_markdown_bytes(data)
对于 CSV,可以显式指定格式:
markdown = anydoc.to_markdown_bytes(data, "csv")
还可以通过:
document = anydoc.to_document(data)
进入文档模型,以进一步处理嵌入资源。
Rust
Rust 版本可以从文件路径开始:
let markdown = anydoc::to_markdown("report.docx")?;
也可以直接从字节数据进行转换:
let markdown = anydoc::to_markdown_bytes(&bytes, None)?;
对于 CSV,可以通过 anydoc::Format::Csv 明确指定格式;还可以调用 anydoc::to_document 获取文档模型。
格式自动识别
anydoc 的格式识别优先读取文件内容中的格式标记,并在无法识别时使用路径或扩展名作为后备方式。仓库给出的 Rust 接口包括:
Format::from_bytes(&bytes);
Format::from_extension("pptm");
Format::from_path(Path::new("report.odt"));
Node.js 与 Python 也分别提供对应的格式识别函数。
错误处理
仓库定义了多种转换错误,包括 Unsupported、Malformed、Encrypted、ResourceLimit、MissingPart 和 Io。Node.js 中对应的错误代码包括 unsupported、malformed、encrypted、resourceLimit、missingPart 和 io。其中,图片型 PDF 被列为 unsupported 的示例。
例如 Node.js 可以根据错误代码,将加密文件或无法支持的文件记录下来并跳过:
try {
return await toMarkdown(path);
} catch (error) {
if (error.code === 'encrypted' || error.code === 'unsupported') {
return null;
}
throw error;
}
嵌入图片与对象
仓库的示例程序说明,Markdown 本身不承载这些嵌入字节,因此资源处理需要额外执行一次文档模型读取。示例通过 toDocument 获取 document.assets,然后依据资源媒体类型写入独立文件。
anydoc的案例应用
案例一:使用 CLI 将 Word 文档转换为 Markdown
仓库 Quick Start 直接给出了使用 CLI 转换 Word 文档的方式:
npx @firecrawl/anydoc report.docx
该命令将生成的 Markdown 输出到标准输出。对于 PowerPoint,可以指定输出文件:
npx @firecrawl/anydoc slides.pptx -o slides.md
对于 CSV,则可以通过标准输入传入数据并显式指定格式:
npx @firecrawl/anydoc - --format csv < data.csv
因此,仓库示例覆盖了文件路径输入、输出到文件以及标准输入三种 CLI 使用方式。
案例二:Node.js 中按内容识别格式并导出资源
仓库 examples/convert.mjs 提供了更完整的 Node.js 转换示例。程序首先读取输入文件字节,在没有显式 -f 参数时,先通过文件内容进行格式识别,再以路径作为后备识别方式。识别成功后调用 toMarkdownBytes 生成 Markdown;当指定输出路径时写入文件,否则输出到标准输出。
示例程序还支持 --assets 参数。此时程序会再次调用 toDocument,访问 document.assets,根据资源媒体类型确定扩展名,并将资源字节写入指定目录。这一方式对应仓库关于"Markdown 保留替代文本、原始资源继续保留在文档模型"的设计。
案例三:Python 批量转换入口的实现方式
仓库 examples/convert.py 展示了 Python 端的命令行转换程序。程序读取输入文件字节,在没有使用 -f 参数时调用 anydoc.format_from_bytes 进行内容识别,再以 anydoc.format_from_path 作为后备方式。随后通过 anydoc.to_markdown_bytes 生成 Markdown,可选择写入输出文件或直接写到标准输出。
该示例同样支持 --assets 参数:当启用该参数后,程序取得 anydoc.to_document(data, format) 返回的文档模型,遍历其中的 assets,根据资源类型生成文件扩展名,再将资源数据写入目标目录。
案例四:Rust 中实现完整的文档转换命令
仓库 examples/convert.rs 给出了 Rust CLI 示例。其调用方式为:
cargo run --example convert -- <file> -f csv -o out.md --assets dir
示例支持输入文件、显式格式、输出文件以及资源目录等参数;如果未通过 -f 指定格式,则先从文件内容检测,再使用文件路径进行后备识别。
在转换阶段,示例读取输入文件后调用 anydoc 的转换接口生成 Markdown,并根据是否指定输出路径决定写入文件还是继续输出;其整体处理流程与 Node.js 和 Python 示例保持一致,体现了 anydoc 围绕统一格式检测、Markdown 输出及资源提取构建的跨语言 API 设计。
案例五:在浏览器中通过 WebAssembly 转换文档
仓库提供 @firecrawl/anydoc-wasm 作为 WebAssembly 绑定。基本使用方式是先初始化模块,然后从字节数据调用 toMarkdownBytes:
import init, { toMarkdownBytes } from '@firecrawl/anydoc-wasm';
await init();
const markdown = toMarkdownBytes(bytes);
CSV 等无法仅依靠内容签名识别的格式可以显式指定:
const markdown = toMarkdownBytes(bytes, 'csv');
此外,WASM 版本也能通过 toDocument 获取文档模型,并通过 formatFromBytes 单独执行格式识别。仓库还说明 WASM 调用是同步的,并且运行在调用线程上,因此需要保持主线程响应时,应将转换放到 Worker 中。