PDF 转 Word/Markdown 到底是怎么实现的?聊聊 OCR、解析二进制和「猜结构」这件事

最近折腾文档上传功能,踩到一个看起来很简单、实则坑得离谱的需求:把用户传上来的 PDF 转成结构化的 Markdown。我一开始天真地以为,「不就是把文字抠出来嘛,能有多难」。结果一头扎进去,才发现这事的难点根本不在抠字,而在「猜结构」。这篇就把我重新理解的这套底层原理记一下,顺便回答那个被问烂的问题:PDF 转 Word/Markdown,到底是靠 OCR,还是靠解析二进制,还是别的什么黑魔法?


先认清一个反直觉的事实:PDF 不是「文档」,是「打印稿」

这是整件事的根:PDF 内部存的,根本不是段落、标题、表格,而是一堆绘制指令。

它的内容流大概长这样:「在坐标 (x, y) 用 12 号宋体画一个字符『法』」「从 (a, b) 到 (c, d) 画一条线」「在这个矩形区域里贴一张图」。仅此而已。PDF 只关心一件事——打印出来长什么样。它压根没有「这一块是标题」「这是一张表格」「应该先读左栏还是右栏」这种概念。

这些结构信息,在生成 PDF 的那一刻就被丢掉了。当年从 Word/LaTeX 导出 PDF 时,「标题、段落、表格」全被拍扁成了一堆带坐标的画字指令。

而且 PDF 还分两种,差别巨大:

  • 数字版(born-digital):从 Word/LaTeX 直接导出的,内部带「文字层」——每个字符是什么、在什么坐标,都老老实实存着。
  • 扫描件:本质就是一堆页面图片,一个字符都没有。你在里面搜「合同」是搜不到的,因为里面根本没有「合同」这两个字,只有像素。

所以 PDF → 结构化格式这件事,本质上是:把当年丢掉的结构,重新猜回来。难就难在这个「猜」字。


几种手段,回答「OCR 还是操作二进制」

实际工程里不是二选一,而是几种手段组合上阵:

① 解析 PDF 二进制 / 文字层

直接读 PDF 内部的内容流,把「字符 + 坐标」抠出来。注意:这是解析,不是 OCR——它读的是 PDF 里现成的文字数据,不需要任何视觉识别。但抠出来的是一地散落的、带坐标的文字碎片,离「结构」还差十万八千里。这条路只对数字版有效。

② OCR(光学字符识别)

把页面渲染成图片,再用视觉模型一个字一个字认出来。只有扫描件、图片型 PDF 才必须走这条路,或者当作数字版抠不干净时的兜底。很多人以为 PDF 转文字 = OCR,其实大错——数字版根本用不着 OCR。

③ 版面分析(layout analysis)

这才是真正「有智商」的一步。用 ML 模型看整张页面,判断「这块是标题 / 正文 / 表格 / 图 / 列表」,并且定出阅读顺序(分栏排版尤其需要它,不然左右栏会串成一锅粥)。

不管是 ① 解析还是 ② OCR,拿到的都只是一堆散字。真正把「散字」变回「结构」的,是这第 ③ 步版面分析。OCR 只是其中一块拼图,而不是核心。

④ 表格结构识别

表格是重灾区。专门的模型把表格区域还原成行 / 列 / 单元格,连合并单元格都要还原。光知道「这里有张表」不够,还得知道它到底几行几列、哪些格子是合并的。

⑤ 端到端 VLM(视觉大模型)

近两年的新路线:把整页图片直接喂给多模态大模型,让它一口气生成 Markdown(Nougat、GOT-OCR 这类)。一个模型全包,省心。但代价是——它会幻觉。模型可能会「脑补」出原文没有的内容。在法律、金融这种严肃场景,一个数字编错、一个条款编造,后果很严重,所以这类场景我会很谨慎,甚至直接拒掉 VLM。

👉 所以那个问题的答案是:用 OCR 还是解析二进制,取决于 PDF 类型——数字版主要靠 ① 解析 + ③ 版面分析;扫描件必须 ② OCR + ③ 版面分析。OCR 远不是全部,真正把散字变结构的功臣是版面分析。


以 Docling 为例:一条「管线」是怎么跑的

我最后选了 Docling 这条非 VLM 的管线路线,它的流程很能说明问题:

  • 第一步:判断 PDF 类型。数字版 → 解析文字层;扫描件 → 渲染成图片再 OCR。
  • 第二步:版面分析模型扫一遍,标出哪块是标题、正文、表格、图,并定好阅读顺序。
  • 第三步:表格模型(如 TableFormer)专门把表格还原成行列单元格。
  • 第四步:把上面的结果组装成一棵结构树——带层级的标题、段落、表格、页码、阅读顺序,全在树上。
  • 第五步:把这棵树序列化成 Markdown 或 JSON。

关键在于:它的「智商」来自版面分析 + 表格这两个专用小模型(加起来也就几百 MB),不是大语言模型。好处很实在——不编造内容(它只是在分类和定位,不生成文字)、显存需求小、能在 CPU 上跑。对法律文档这种容不得幻觉的场景,这种「笨但靠谱」的路线反而更安全。


插一段:那个「本地小模型」到底在干嘛?

我每次跟人讲「PDF 转结构得跑一个本地小模型」,对方第一反应都是:这模型是干嘛的?为啥非它不可?这块我自己也是绕了一圈才真正想明白,单拎出来讲透——它就是上面管线里第二步那个版面分析模型(layout analysis model),是整条线里「把散字变结构」的核心。

它是什么

它是一个专门认「文档版面」的小型视觉模型。你可以把它理解成一个专门看文档页面的目标检测模型——思路跟 YOLO / DETR 那类一脉相承,只不过它的训练数据全是各式各样的文档页面(论文、合同、财报、扫描件……)。最关键的一点:它是专用小模型,几百 MB、CPU 就能跑,不是大语言模型。别被「模型」两个字唬住,它跟动辄几十上百 G 的 LLM 完全不是一个量级。

它干嘛:输入 → 输出

  • 输入:渲染好的页面图片,再配上前面从 PDF 里抠出来的「字符 + 坐标」。
  • 输出:在页面上框出一块块区域,给每块打标签——标题(还会细分一级 / 二级…)、正文段落、列表项、表格、图、图注、页眉、页脚、脚注、公式……然后再定出阅读顺序:先读哪块、后读哪块。分栏排版时这步尤其要命,没有它,左右栏会被串行读成一锅粥。

为什么非它不可

因为 PDF 只会告诉你「坐标 (100, 200) 这里有个字符 A」,它不带任何「这是标题」之类的标签。你解析完拿到手的,是一摊带坐标的散字。这个模型干的活,就是把当年生成 PDF 那一刻丢掉的标签,重新贴回去——它看字号大小、位置、是否加粗、行间距这些视觉线索,判断出「顶部这行又大又粗 = 标题、下面这块 = 正文、这个规整的网格 = 表格」。

打个比方:有人递给你一页纸,字都印得清清楚楚,但所有格式被抹平了——你看不出哪行是标题、哪行是正文。这个模型就像一个人瞟一眼版面,凭直觉就能重新认出「这是标题、这是正文、那是表格」,再把标签一一标回去。

它跟我们最终想要的东西是怎么挂上钩的?很直接:它把某块标成「二级标题」,转换器就给这块配一个对应的标题层级(heading level)——后面不管你是转 Markdown 还是转 Word,那个标题层级就是从这儿来的。没有它,你顶多得到一坨没有任何标题层级的纯文本。

它还有两个搭档

顺带提一句,它不是孤军奋战,旁边还跟着两个同样是「专用小模型 / 专用模块」的帮手:

  • 表格模型(如 TableFormer):当版面模型说「这块是表格」之后,由它专门把这块还原成行 / 列 / 单元格,连合并单元格都要还原回来。
  • OCR 模型(如 EasyOCR):只有遇到扫描件(纯图片、没有文字层)才上场,负责「看像素认字」。数字版 PDF 自带文字层,这一步直接跳过。

👉 点睛:它是个专用小模型,干的是分类 / 检测(判断这块是不是标题、框出表格在哪),它不「生成」任何文字内容,所以既不会编造、显存需求也极小。这恰好跟 VLM 那条路线形成对照——VLM 是用一个大模型把整页「看完直接写出」 Markdown,因为它在「生成」,就可能脑补出原文根本没有的内容(幻觉)。所以越是严肃场景,我越宁可用这种「小模型只分类、不生成」的稳妥路线。


那市面上的「PDF 转 Word」工具呢?

Adobe、WPS、Smallpdf 这些,原理是一样的,只是输出端反过来了:

  • 输入侧:和上面完全一致——解析文字层 + 版面分析,扫描件再加 OCR,把结构猜出来。
  • 输出侧:把还原出的结构生成一个 .docx 文件。而 .docx 的本质是 OOXML,说白了就是一个 zip 压缩包,里面装着一堆 XML

所以「PDF 转 Word」= 解析 PDF + 版面分析(± OCR)→ 生成 Word 二进制。难点依然在前半段的「猜结构」,后半段「写 docx」反而是机械活。


反差收尾:为什么 Word → Markdown 反而简单到离谱

讲完 PDF 的苦,再看 Word 转出来,简直是天堂。同样叫「格式转换」,难度差着量级。

原因就一句话:.docx 本身就是结构化的 XML。段落、标题 1/2/3、表格,在 OOXML 里都是显式的 XML 元素,明明白白写着「我是标题」「我是表格」。结构从头到尾就没丢过。

所以 Word → Markdown:

  • 不需要 OCR;
  • 不需要版面分析;
  • 不需要任何 ML 模型去「猜」。

它只是——解压 zip + 读 XML + 翻译成 Markdown,几十毫秒搞定,一个纯 JS 小库就够了。

一句话对比:
PDF → 结构 是「结构丢了,要靠 ML 重新还原」——难、重、还可能错。
Word → 结构 是「结构本来就在 XML 里,照着读一遍翻译就行」——简单、轻、不会错。

这也解释了我开头那个疑惑:为什么同样是「格式转换」,PDF 那条线得专门起一个带模型的服务、占显存、还得防幻觉;而 Word 那条线,扔进一个几十 KB 的前端库就完事了。差别不在工具懒不懒,而在于——源头有没有把结构丢掉

说到底,文档格式转换的全部难度,都浓缩在这一个问题里:信息在哪一步被拍扁了,你就得在哪一步把它捞回来。PDF 是在「打印」那一刻拍扁的,所以你得用模型一点点捞;Word 压根没拍扁,照抄就行。

感谢您的收看 祝你天天开心~
暂无评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
上一篇
下一篇