PDF、Word、Excel、PPT转成结构化的Markdown,这2个工具足够
- 2026-11-05 17:15:40
把 PDF 原样丢给模型
文档转 Markdown
两个开源项目洗一遍
把 PDF、Office、EPUB 变成模型能读的干净 Markdown,顺手把选型判据和四个坑一起讲清。
技术干货 · 日常上手
📦 5 Parts + Conclusion
👉 滑动
PART 01
三个前提
WHY MARKDOWN
PART 02
跑通两个工具
QUICK START
PART 03
怎么选
COMPARE
PART 04
接进流水线
PIPELINE
PART 05
四个坑
PITFALLS
PART ///
写在最后
收尾
一句话先说清
大模型读的是 token,PDF 和 Office 给的是二进制布局。中间那一步「转成结构化的 Markdown」,过去要手写脚本,现在有两个开源项目可以直接用。
01
PART
三个前提:为什么要转、两个项目各是什么
WHY MARKDOWN
模型看不到「这一行是标题、这三列是一张表」,它只看到一串 token。PDF 和 Office 文件里,标题层级、表格边界、列表编号都靠排版坐标画出来,不做转换直接抽文字,结构基本就丢了——表格会散成一行行句子,跨页的段落会断在奇怪的位置。Markdown 用最少的标记把这些结构保住,而且是 token 效率最高的形式之一,这正是 MarkItDown 官方文档给出的第一个理由。
两个项目的定位不一样,先分清楚。
markitdown
微软开源,Python 包,2024 年 11 月起就在维护,约 19 万星,MIT 许可。覆盖面最广:PDF、Word、PowerPoint、Excel、图片、音频、HTML、CSV、JSON、XML、ZIP、YouTube 链接、EPUB 都在支持列表里,另有一套插件与云端增强机制。
anydoc
Firecrawl 在 2026 年 8 月新开源,Rust 写核心,约 2.2 万星,MIT 许可。14 种格式走同一个文档模型、同一个序列化器,输出风格完全一致;除命令行外还提供 Node、Python、Rust 与浏览器 WASM 绑定。
选型其实只有两个问题:要不要 OCR,决定了选型的一半;输出保真度够不够用。速度排在后面——两者差的那点时间,在一次人工核对面前可以忽略。
02
PART
第一步:十分钟跑通两个工具
QUICK START
markitdown:覆盖最广的那一个
安装时把可选依赖一起装上,省得后面遇到 PDF 报缺库:
pip install "markitdown[all]"
# 也可以按需装:pip install "markitdown[pdf,docx,pptx]"
命令行用法就是一条命令进出:
markitdown 报告.pdf -o 报告.md
markitdown 报告.pdf > 报告.md
cat 报告.pdf | markitdown
想在脚本里调用,接口只有一个对象:
from markitdown import MarkItDown
md = MarkItDown()
print(md.convert("报告.pdf").markdown)
anydoc:2026 年新开源的快枪
最省事的跑法是用 npx,第一次运行会自动下载对应平台的预编译二进制:
npx @firecrawl/anydoc 报告.docx
npx @firecrawl/anydoc 幻灯片.pptx -o 幻灯片.md
npx @firecrawl/anydoc - --format csv < 数据.csv
要留一个常驻命令,或者在自己的代码里调用:
npm install -g @firecrawl/anydoc
pip install firecrawl-anydoc
npm install @firecrawl/anydoc
import anydoc
markdown = anydoc.to_markdown("报告.docx")
它还有一个能力值得单独提:装 @firecrawl/anydoc-wasm 之后可以直接在浏览器里转换,文件不出本机。
03
PART
第二步:怎么选——一张对照表
COMPARE
把两者的差异压到一张表里,逐行看就行:
最后一行是选型时最容易被忽略的。anydoc 星数涨得快,但开源才两个月、最近一次提交停在 2026 年 8 月底,新项目最大的变量是发版节奏。要把它放进生产流水线,先观察它一段时间的发版;如果是离线批处理、坏了能立刻换回,那它现在的性价比很高。
格式覆盖的具体边界
对照表里的「格式覆盖」只是一句结论,具体到扩展名要单独看:
| .doc | ||
| .ppt | ||
| .xlsx | .xls | |
| .odt | ||
| .rtf | ||
手里还有 .doc、.odt、.xlsb 这类老格式时,先确认工具在不在覆盖范围里。anydoc 的 14 种是它对外宣称的全集,一次装好;markitdown 的格式覆盖靠可选依赖拼起来,所以要用 [all] 装,漏装哪一项,对应的文件类型就会直接报缺库。
04
PART
第三步:接进自己的流水线
PIPELINE
日常用法其实就两类。
一是批量转换,把目录里的 Office 文件全部转成同名 Markdown:
for f in ./docs/*.docx; do
npx @firecrawl/anydoc "$f" -o "${f%.docx}.md"
done
二是交给编码代理。anydoc 本身就打包成了一个 Agent Skill,装完代理就能自己读 Office 文档:
npx skills add firecrawl/anydoc
转换之后得到的 Markdown 再进入切块与索引,比直接对 PDF 抽纯文本要稳:标题层级还在,切块可以按标题走;表格还在,不会被切成几段无意义的碎片。转成 Markdown 只是第一公里,它负责让后面的处理有结构可依,不负责替你理解文档。
05
PART
四个坑
PITFALLS
!扫描件不会自己变成文字 🕳
扫描件不会自己变成文字。anydoc 在本地不做 OCR,遇到扫描页直接失败并在退出码里体现(CLI 退出码 3,提示形如 anydoc: pages 2, 5-7 of 12 need OCR)——这比静默丢页好,但需要你显式开托管 OCR。markitdown 那边有个相反的坑:OCR 插件的 llm_client 没配时不会报错,只是安静跳过,输出看起来正常,图片里的文字却全没了。
!把项目方自测的分数当作结论 🕳
把项目方自测的分数当作结论。anydoc 仓库里那张「14 种格式全覆盖、中位 4.4 毫秒」的基准表是项目自己跑的,脚本在仓库的 bench/ 目录,语料不对外分发。它说明作者在乎这件事,不能替代你拿真实文档做的对比。
!批量跑时按错误类型分流 🕳
批量跑时按错误类型分流。anydoc 把加密、需 OCR、结构不可用等分成了不同的错误类型。全都塞进一个 except 里吞掉,最后只会得到一句「有一些文件没转成功」,真正的原因全丢了。
!不可信输入与云端外发 🕳
不可信输入与云端外发。markitdown 官方明确提示:它按当前进程的权限做输入输出,和 open() 同级,处理外部上传的文件要用最窄的转换入口并做输入净化。anydoc 的托管 OCR 会把整份文档发往云端,而且不支持只送某几页,涉密文档不要开这个开关。
///
LAST
写在最后
WRAP UP
两个项目都是 MIT,都能一条命令跑起来,所以别在选型上纠结太久:先跑通,再拿十份真实文档各过一遍。
用你自己的十份文档各跑一遍,比任何榜单都准。真正决定成败的从来不是转换器,而是你喂进去的那份文档里,到底有没有模型需要的结构。
如果这篇内容对你有帮助,欢迎点赞、在看、转发三连,我们下篇见。
既然看到这里了,如果觉得有用,随手点个赞、在看、转发三连吧。
THANKS FOR READING