1. Word 转 Markdown 的难点:格式迁移的本质是保留“文档骨架”
做内容迁移的朋友应该都有感触:Word 文档躺在本地盘里时没什么存在感,一旦你想把它挪进博客、知识库、Wiki 或者 Git 仓库,问题就来了——Markdown 是纯文本标记语言,Word 是富文本排版工具,两者之间不存在“无损复制粘贴”这条路。
我接手过一批产品手册的迁移,几十份 docx,里面布满技术截图、表格和公式。当时我试过最原始的办法:打开 Word,全选复制,粘贴到 Markdown 编辑器。结果图片全部变成了一堆data:image/png;base64或者直接丢失,表格排版散架,公式变成乱码。这种状态别说发布,自己看着都想砸键盘。
所以“Word 转 Markdown”这件事,核心痛点从来不是“怎么把文字弄出来”,而是三个关键问题:图片能不能完整保存下来并正确引用、标题和列表的层次结构能不能保留、公式表格这类特殊元素能不能继续被人看懂。这三个问题,就是我接下来要展开的全部内容。
1.1 docx 到底是什么:一个装着图片和 XML 的压缩包
很多人不知道,docx 本质上是一个 ZIP 压缩包。你把后缀改成.zip,解压开就能看到一堆文件夹:word/document.xml是正文内容,word/media/目录下存放着所有嵌入图片,word/styles.xml是样式定义,word/numbering.xml是编号规则。
这解释了一件很重要的事:Word 转 Markdown 的过程,本质上不是“翻译排版”,而是“解析 XML 结构,重构 Markdown 语法树”。图片也不是“导出”出来的,而是从压缩包里“提取”出来的。我当时意识到这个原理后,对整个转换流程的信心立刻就不一样了——因为我知道图片一定在某个地方等着我,问题的关键只是怎么把它提取出来并建立正确的引用关系。
1.2 为什么直接复制粘贴总是翻车
复制粘贴走的是剪贴板,剪贴板只保留两类东西:文本和富文本 HTML。Word 会把内容转成一段极其臃肿的 HTML 塞给编辑器,Markdown 编辑器一般会把它转成原生 Markdown 或者保留 HTML 片段。
问题出在图片上。剪贴板里的图片如果不经过特殊处理,要么被转成 base64 内嵌字符串,要么干脆丢弃。你贴在 Typora 里看到的图片,换一个平台或者换个编辑器可能就完全加载不出来。更别提表格的边框、合并单元格、公式的 OMML 结构,在剪贴板里早就支离破碎了。
所以,如果只是偶尔转一篇简单文档,复制粘贴还能凑合;一旦涉及批量、涉及图片、涉及公式,就必须换成真正的文档转换工具,让程序去解析 docx 的文件结构,而不是依赖剪贴板。
1.3 你不只是在转格式,而是在重新组织文档结构
我后来总结了一个观点:Word 转 Markdown 的核心不是“保留 Word 格式”,而是“保留文档骨架”。所谓骨架,就是标题层级、段落结构、列表嵌套、表格行列、图片引用、链接、脚注这些语义化元素。
为什么这么说?因为 Markdown 本来就不可能做到像素级还原 Word。它有它自己的排版哲学:用#表示层级,用-表示列表,用|表示表格。你在 Word 里调过的行距、缩进、段前段后间距,转到 Markdown 里一概不存在,也不需要存在。真正需要保留的,是那些“就算换一种排版方式也不能丢”的信息结构。把这个想通了,你在转换时就不容易钻牛角尖——某条下划线丢失了不重要,但某个三级标题变成了正文,这就很要命。
2. 转换前的文档体检:样式、图片嵌入和公式必须提前修复
转换工具再强大,也扛不住源文件本身风控。我见过太多人跳过这一步,结果转出来的 Markdown 惨不忍睹,还以为工具不行。实际上,大部分问题出在 Word 文档的质量上。转换前花十分钟体检,能省下来两小时的清理时间。
2.1 检查标题是否用了“样式”,而不是手动调大字号
这是最容易被忽略、又影响最大的一点。Pandoc 这类工具识别标题,靠的是 Word 样式中的“标题 1”“标题 2”等内置样式,而不是看字号大小。如果原文是用“选中文字,把字号改成 20 磅加粗”这种方式模拟标题,那么在转换工具眼里,它就是一个普通段落,会被转换成纯文本,标题层级全没了。
体检方法很简单:在 Word 里打开“开始”工具栏,看文档左侧是否有对应的标题样式块。如果发现文章里的“标题”都是手调格式,那么最省事的修复方式是:选中文字,直接点击“标题 1”“标题 2”样式,哪怕字号暂时不理想也别管,Markdown 输出后用 CSS 或主题去控制实际展示效果。
2.2 图片嵌入、浮动和缺失引用的排查
在 Word 里,图片有两种存在方式:嵌入型(inline)和浮动型(floating)。嵌入型图片跟文字在同一个段落流里,转换工具容易定位;浮动型图片(比如设置了文字环绕)有时候会被当作 drawing canvas 处理,转换后位置会漂移,甚至会脱离上下文。
还有一个常见隐患是图片不可见。有人习惯用“显示标记”功能,但 Word 文档里可能出现这样一种情况:图片被设置成了“嵌入”到文本框或形状里,表面看是一张图,实际是一个 OLE 对象或浮动画布。这种图用 Pandoc 严格意义上也能提出来,但引用位置往往对不上。
转换前建议快速翻一遍文档,把重要的图都检查一遍是否正常显示。如果发现某张图显示为空白框或者灰色占位,多半是嵌入方式有问题,需要先在 Word 里重新插入一次。这个步骤很繁琐,但确实能避免转换完发现关键截图缺失的尴尬。
2.3 公式的三种存在形式:OMML 公式、MathType 对象和图片公式
做技术文档的人对数学公式肯定不陌生。Word 里的公式有三种“前世今生”:
- 原生公式:用 Word 的“插入→公式”创建的 OMML 结构,这是转换工具最喜欢的形式,可完整转成 LaTeX。
- MathType 公式:如果是老文档,公式可能是 MathType 对象(本质是 OLE 嵌入),Pandoc 识别不了,会被当成嵌入对象处理,输出基本等于丢失。
- 图片公式:从 PDF 或网页里截图粘贴进来的公式,本质就是一张图片,转出来的就是
,没有任何可编辑性。
体检时,看文档里公式是否能直接用鼠标光标选中并编辑。MathType 公式通常会在双击时弹出 MathType 编辑器。如果遇到大量 MathType 公式,最靠谱的补救方案是在 Word 里逐个双击进入 MathType,然后用其自带的转换功能把公式转成 Word 原生公式(OMML),再执行转换。这个环节虽然费时,但对那些公式含量极高的文档,这是唯一能保住“可编辑公式”的路。
2.4 清理空行、手动编号与表格的合并单元格
Word 文档里最常见的坏习惯,是用回车键打出一堆空行来表示段落间距。转换后,这些空行会变成 Markdown 里的多余空行,虽然不致命,但读起来非常松散。用查找替换把^p^p(连续两个段落标记)换成^p,可以快速清理。
另一个坑是手动编号。很多人不用 Word 的自动编号列表,而是手动输入“1、2、3、”。这种列表在转换后不会被识别成 Markdown 的有序列表,而是变成普通段落“1、 内容”。遇到这种情况,要么在原文里改成自动编号列表,要么接受转换后手动给 Markdown 加1.前缀,没有别的捷径。
表格的合并单元格也值得提前观察。Pandoc 对合并单元格的支持是有限度的,跨行合并(rowspan)有时会被拆开或者变成空单元格;跨列合并稍微好一些,但输出为 Markdown 的 pipe table 时,列数可能对不齐。我的建议是:如果表格结构特别复杂(比如多层表头、多重合并),在 Word 里尽量简化,或者在转换后改用 HTML 表格区块嵌进 Markdown 里。
3. 工具选型对比:Pandoc 为什么是保留图片和格式的最佳选择
在正式动手前,先把工具选明白。市面上能处理 Word 转 Markdown 的工具不少,但定位差异很大,选错了容易白折腾。
| 工具 | 优点 | 缺点 | 适合场景 |
|---|---|---|---|
| Pandoc | 开源免费、跨平台、支持 word/media 图片提取、公式能转 LaTeX | 命令行,初学者略有门槛 | 批量转换、复杂文档、需要稳定输出的场景 |
| mammoth | 专门面向 docx 解析,输出的 Markdown 干净无垃圾标签 | 公式支持弱、复杂表格容易丢细节 | 纯文本为主的文档,追求“干净” |
| Typora 粘贴 | 所见即所得,简单快捷 | 图片会转成 base64 或需要手动设置,批量能力差 | 临时转换、单篇短文 |
| 在线转换网站 | 不用安装,操作简单 | 隐私风险高、图片路径不可控、转换质量参差不齐 | 不涉密、不追求细节的应急场景 |
| python-docx 定制脚本 | 可完全控制逻辑 | 需要编程,工作量较大 | 有特殊格式需求,且愿意投入开发成本 |
3.1 Pandoc:一个命令解决 90% 的问题
Pandoc 是文档转换界的瑞士军刀。它支持 docx 转 Markdown,并且默认就能把嵌入图片提取到指定目录,把 Word 内置标题映射成对应层级的 ATX 标题,把有序列表、无序列表、表格、链接、脚注都转换成标准 Markdown 语法。更关键的是,它的转换逻辑基于 Pandoc AST(抽象语法树),这意味着你不只是在“粘规则”,而是在“映射语义”。Word 里标记为“标题 1”的文本,一定会变成#,绝不会因为字号变化而判断失误。
在公式方面,Pandoc 默认会把 Word 原生 OMML 公式转换成 LaTeX 数学语法,行内公式用$...$,块公式用$$...$$。这一步对我来说是决定性的——我做技术迁移时最怕公式变成图片,而 Pandoc 恰恰能保住公式的可编辑性。
3.2 mammoth:追求干净的另类方案
mammoth 是一个专门解析 Word 文档的库,它也有命令行工具,目标很纯粹:把 docx 转成干净的 HTML 或 Markdown。它的理念是“关注语义,忽略排版”,所以输出里很少出现垃圾标记,标题、段落、列表这些基础结构处理得很干净。
但 mammoth 有两个明显短板:一是公式支持不完整,二是表格处理能力有限。我实测过带公式的工程文档,mammoth 对 OMML 基本无解,输出出来公式就是原始 XML 或者干脆消失。相比之下,Pandoc 的处理要成熟得多。
所以我的判断是:mammoth 适合“文章型”文档,不适合“手册型”文档;适合做在线预览的轻量转换,不适合做需要长期维护的知识库迁移。
3.3 在线转换与 Typora 粘贴:适合应急但不适合批量
在线转换网站的痛点很明显:你永远不知道它把你文件传到哪个服务器了;图片提取的逻辑也不透明,包下载下来经常是一堆哈希命名的图片,路径对不上。Typora 的粘贴功能虽然方便,但它在“复制粘贴”场景下不容易保留原始图片文件,更多的是把图片放到本地相对路径,最终发布时还得重新配置。
这两个方案不是不能用,而是不适合当作主力。诚实的建议是:应急用一次可以,批量迁移就算了,别给自己留后患。
3.4 我的工具组合策略
当我真正处理那批产品手册时,采用的组合是:Pandoc 为主力转换,python-docx 做前置体检和自定义修复,最后人工过一遍渲染结果。这样既拿到了标准的 Markdown 结构,又能针对特殊情况写脚本来兜底。接下来要讲的实操过程,基本都是围绕这套组合展开的。
4. Pandoc 实操:从 docx 到 markdown 的完整命令与图片路径处理
在折腾过各种工具之后,我可以负责任地说,Pandoc 是当前把“保留图片”和“保留格式”做得最平衡的方案。下面是从零开始的完整操作。
4.1 安装 Pandoc 和基本命令
安装 Pandoc 很简单。Windows 上可以用 winget:
winget install --id JohnMacFarlane.PandocmacOS 上可以用 Homebrew:
brew install pandocLinux 上,Ubuntu 系直接用 apt:
sudo apt-get install pandoc装好之后,在命令行里进到 docx 所在的目录,执行这条最基本的转换命令:
pandoc "示例文档.docx" -t markdown --extract-media=./assets -o "示例文档.md"说下参数含义:
-t markdown:指定输出格式为 Markdown。如果不指定,Pandoc 会默认输出 HTML。--extract-media=./assets:关键参数。它会把 docx 内嵌的所有图片提取到./assets/media/目录,并把 Markdown 中的图片引用路径改成相对路径。-o 示例文档.md:指定输出文件名。
转换完成后,打开 Markdown 文件,你会看到类似这样的引用:
这是一段文字,下面是一张架构图: 图片确实被提取出来了,毫发无损。这个方案比任何“复制粘贴再转存”都靠谱。
4.2 --extract-media 参数:图片是如何被提取和引用的
如果你好奇图片为什么能这么“乖”,我解释一下内部的逻辑:docx 是 ZIP 包,里面所有图片都集中在word/media/目录。Pandoc 在解析 document.xml 时,一旦发现图片引用关系,就会把对应文件从压缩包里抽取出来,按顺序命名——通常就是image1.png、image2.png这样的编号。然后把 document.xml 里的r:embed引用替换成 Markdown 图片语法。
这里有一个需要注意的地方:图片的编号顺序不是按你在 Word 里看到的顺序来的,而是按文档内部的引用 ID 排序。比如文档里先插入了图三,再插入图一,提取出来的名字可能是image1、image2,但具体哪张是哪张,只能通过图片内容去对应。所以,如果对图片文件名有强制要求(比如博客平台要求命名成architecture-overview),最好转换后再做一次批量重命名。
另外一个不知道算不算技巧的经验:--extract-media跟-s(standalone)没有强绑定关系,但如果想要一个带完整元数据的 Markdown(比如带有 Frontmatter),建议加-s。这个参数会让 Pandoc 把标题、作者、日期等信息写入 YAML 元数据块,后面接到博客系统时很省事。
4.3 表格类型选择:pipe table 还是 grid table
Pandoc 的 Markdown 输出里,表格有两种主要形态:pipe table 和 grid table。
- pipe table 就是我们最常见的
| 列1 | 列2 |这种紧凑写法,兼容性好,GitHub 和大多数 Markdown 编辑器都支持。 - grid table 是 Pandoc 自定义的“网格表格”,用
+---+画边框,能表达更复杂的单元格结构,但兼容性差很多,换到别的平台可能渲染异常。
实际上,Pandoc 在默认-t markdown时会根据表格的复杂度自动选择表格类型。遇到带合并单元格或者多行表头的,它可能会选择输出 grid table;而标准行列表格则输出 pipe table。
如果你的目标是 GitHub、知乎或者公司 Wiki,多半希望强制使用 pipe table。有两个方式:
- 加
-t gfm,GitHub 风格 Markdown 会强制输出 pipe table。 - 加
-t markdown-pipe_tables可以让 Pandoc 尽量输出 pipe 表格,但复杂表格它依然只能退回到网格表格。
我的实际建议是:分两步走。第一步用默认-t markdown转换,看看主要表格都是什么形态;如果绝大多数表格可以用 pipe table 表达,那就把目标定为 pipe table,无法表达的部分单独在 HTML 区块里兜底。
4.4 用 gfm 还是 markdown 格式:目标平台决定参数
这个选项看起来很细,但影响很大。
-t gfm:生成 GitHub 风格的 Markdown。它强制 pipe table,对任务列表复选框、删除线、自动链接等有更明确的输出。缺点是某些 Pandoc 扩展(比如 raw HTML 内嵌)在 gfm 里会被限制,适合以 GitHub/GitLab 为主要托管平台的场景。-t markdown:生成 Pandoc 最完整的 Markdown 方言。它能输出更丰富的结构,比如脚注、definition list 等,也允许内嵌 HTML。缺点是有些语法在目标平台(尤其是知乎这种对 Markdown 支持残缺的平台)上可能不生效。
如果目标平台是备案良好的 Wiki 或者静态博客,我偏爱-t markdown,因为它保留了更多信息。如果文档要进 GitHub,那直接-t gfm更干净,省去后续手动调整表格的麻烦。
5. 难处理的特殊情况:公式转 LaTeX、复杂表格、批注与页眉页脚
基础结构转换顺利之后,真正的硬骨头才露出水面。公式、复杂表格、批注、页眉页脚,每一个都够你折腾一阵。
5.1 Word 公式转 LaTeX 的默认行为与 MathType 遗留问题
Pandoc 会把 Word 原生公式转成 LaTeX 数学语法。行内公式形如:
根据牛顿第二定律 $F=ma$,可以推导出动量变化量。块公式形如:
$$ \int_0^t F(\tau) \, d\tau = mv_t - mv_0 $$这个转换是基于 OMML→TeX 的映射,大部分标准数学结构都可以正确转换,包括分数、积分、矩阵、上下标。我测试过包含求和符号、极限、分段函数的工程公式,基本都能还原。
但如果你是老文档,公式是用 MathType 输入的,情况就不妙了。MathType 公式在 docx 中是一个 OLE 对象,Pandoc 默认把它当作嵌入对象,输出的结果可能是这样的:
也就是说,公式变成了一张普通图片。更麻烦的是,MathType 对象在部分解压流程中可能不会出现在word/media/里,而是被封装在word/embeddings/下,除非安装专门的 OLE 处理工具,否则普通提取根本拿不到。
处理方法我在前面体检那节已经提过:在 Word 里打开文档,用 MathType 的“Convert Equations”功能,把整个文档公式统一转换成 Word 原生 OMML,然后再交给 Pandoc。如果文档量很大,别嫌麻烦,这一步是保住公式可编辑性的唯一现实路径。
5.2 复杂表格:合并单元格转换后容易漏行漏列
Pandoc 对表格的处理,比复制粘贴强得多,但复杂表格依然是转化质量的重灾区。多层表头、跨行合并、跨列合并、单元格内嵌列表,这些结构在 pipe table 里绝大多数无法表达。
实测下来,Pandoc 在处理带rowspan的表格时,会把空白合并单元格输出为一个空单元格,看起来格式还在,但渲染出来就是缺了一格。如果原文的合并关系比较复杂,最终 Markdown 表格的列数会错乱,导致内容对不上行。
针对这种情况,我有三条实用建议:
- 如果目标平台支持 HTML 表格,转换后手工把那些复杂表格重写成 HTML
<table>区块,直接塞进 Markdown 文件中。Markdown 本身支持内嵌 HTML,这是最稳妥的兜底方案。 - 如果目标是纯 Markdown 渲染环境,那只能在 Word 里重建简化表格结构,把跨行合并尽量改成跨列合并,或者干脆拆分成多个小表。
- 如果表格里还有第二层内容(比如单元格里嵌了列表或图片),一次转换很难完美,我一般会写一个 python-docx 脚本,读取每个单元格的完整内容,再生成对应的 Markdown 表格字符串。
5.3 批注、页眉页脚和目录:哪些内容注定要舍弃或重做
这里说一个可能会让你失望的事实:Pandoc 默认不会保留 Word 批注。批注在 document.xml 里是独立的 comment 节点,Pandoc 的 docx reader 虽然能识别,但默认不输出到 Markdown。如果批注的内容对你有价值,唯一的办法是先用 Word 导出批注文本,再单独处理。
页眉页脚则完全不在转换范围之内。这倒不是 Pandoc 偷懒,而是 Markdown 的文档模型里根本没有“页眉页脚”的概念。你把这些信息放进标题主体里也怪怪的。我的建议是,把页眉中的文档标题、版本号、页码之类的内容,迁移到 Markdown 的元数据区(Frontmatter)或正文开头的说明文字里。
目录这东西,Word 里的域代码生成的目录,转换前后变成普通列表或直接被忽略。正确做法是转换完用 Markdown 编辑器的目录功能自动生成,或者交给渲染框架(比如 VuePress、Docsify)自动提取标题生成侧边栏。千万别把 Word 目录硬迁移过来,那样排版会非常丑。
5.4 脚注与尾注:Pandoc 处理得很好的部分
好消息是,脚注这块 Pandoc 是加分项。Word 的原生脚注会被转成 Markdown 脚注语法:
这里有一段引用[^1]。 [^1]: 这里是脚注内容。脚注的顺序、编号、正文引用位置都能正确保留。这个特性在做学术类、说明类文档迁移时非常有用,会让最终文档的严谨性好很多。尾注的处理逻辑类似,只是编号位置可能不同,转换后建议人工检查一遍对应关系。
6. 转换后的清理工程:让 Markdown 从“能看”变成“能用”
Pandoc 出品的 Markdown 结构很规整,但离“能直接发布”还有距离。清理工作是整个流程里最费时间的一步,但也是决定成品质量的一步。
6.1 图片路径规范化:统一到一个 assets 目录
转换完的 Markdown 里,图片引用可能是assets/media/image1.png。这个路径在本地能打开,但一旦你要发布到博客或托管平台,最好把图片统一整理到assets/img/或images/这样更常规的目录下。
我常用的做法是两步:先移动文件,再全局替换路径。移动可以用命令行:
mkdir -p assets/img mv assets/media/* assets/img/替换路径时,如果你用的是 VS Code,直接全局搜索assets/media/,替换成assets/img/,非常快。如果图片特别多,也可以写一个 Python 脚本统一处理,顺便把文件名替换成语义化的名字。
还需要留意:如果目标平台会自动给图片做 CDN 加速(比如 GitHub 仓库的图片会走 jsDelivr),那么路径不要写死绝对路径,全部用相对路径,后面接入 CDN 时会更灵活。
6.2 修复嵌套列表和多余的硬换行
这是 Pandoc 一个比较容易出问题的地方。Word 列表有时候会出现“同一列表项里塞了多个段落”的情况,转换后就会变成松散列表(loose list),也就是列表项之间多出空行。空行在 Markdown 里会导致列表渲染中断,看起来像是一个新列表。
处理方式是全局搜索“列表项之间的空行”,把它们删掉。但你无法手动删几百处,所以我建议用一个小正则:
perl -0pi -e 's/(\n- )\n+/\1/g' 示例文档.md如果对正则不熟,用 VS Code 的“查找替换”加正则模式也行。替换完后,用 Typora 或 VS Code 预览,基本就能看出列表是否连贯了。
6.3 核对标题层级:H1 到 H4 之间的跳跃问题
很多 Word 文档在标题层级上是“野路子”的:正文里一会儿用标题 3,一会儿用标题 1,中间还穿插着一些手写强调。Pandoc 会老老实实按样式名映射,但最终层级可能不符合 Markdown 发布规范(比如直接从##跳到了#####)。
清理时,重点检查两件事:
- 是否只有一个
#作为文章主标题。如果多个#,说明文档顶层结构不清晰。 - 标题层级是否连续。如果出现
## 二级标题后面直接跟#### 四级标题,中间缺了三级,建议调整一下层级,或者压缩中间结构。
这一步基本靠人工核对。我在处理几十份手册时,就是打开终稿的目录树,一个个过标题层级,花的时间不少,但最终发布效果非常整齐。
6.4 为博客/文档站生成 Frontmatter 和目录
如果你的 Markdown 要发布到静态博客或文档站,那么需要在文件顶部补上 Frontmatter。Pandoc 的-s参数能带出一些基础元数据,但一般不够用。
我会手动补全类似这样的内容:
--- title: "Word转Markdown(保留其中插入的图片以及Word格式)" date: 2025-01-15 tags: [Word, Markdown, 文档迁移] ---如果文档很长,还可以让渲染框架自动生成目录。GitHub 会自动识别标题生成锚点目录,Typora 里也可以打开“侧边栏大纲”。这一步基本不用在 Markdown 文件里做额外加工,交给工具就行。
7. 批量转换与自动化:几十个 docx 一次搞定的实操脚本
一旦手头有大量 Word 文档,你会发现手动一个文件一个文件转换根本不现实。这个时候,批量脚本是唯一的出路。
7.1 Bash 脚本:一键循环转换并提取媒体文件
在 Linux 或 macOS 环境中,一个简单的 bash 循环就能完成全部工作:
for f in *.docx; do pandoc -s "$f" -t markdown --extract-media=./media/"${f%.docx}" -o "${f%.docx}.md" echo "已转换: $f" done${f%.docx}是 bash 的变量替换,用来去掉后缀名,保证输出的 Markdown 文件与原文件同名。--extract-media=./media/"${f%.docx}"会把每份文档的图片单独存到一个以当前文档名命名的子目录里,避免不同文档的image1.png互相覆盖。
运行前务必干一件事:把所有 docx 放到一个独立的目录,里面只保留需要转换的文档,免得脚本误伤其他文件。
7.2 PowerShell 批量处理:中文文件名和编码的坑
Windows 环境下推荐用 PowerShell 做批量转换,但有几个大坑必须先说。
第一,PowerShell 5.x 的默认编码不是 UTF-8。如果你在脚本里输出的日志包含中文,很容易变成乱码。建议在脚本开头加:
$OutputEncoding = [System.Text.Encoding]::UTF8第二,中文文件名本身没有问题,但某些旧版 Pandoc 在 Windows 下处理含空格或全角符号的路径时可能报错。稳妥的方式是统一用Get-ChildItem获取文件对象,再传$_.FullName给 Pandoc,避免手写路径:
Get-ChildItem -Path . -Filter *.docx | ForEach-Object { pandoc -s $_.FullName -t markdown --extract-media=./media_$($_.BaseName) -o "$($_.BaseName).md" }第三,如果批量转换过程中某一份文档报错,脚本默认会继续执行还是停止?PowerShell 默认遇到非中断错误会继续,但我想让它明显标出来,所以加上try/catch或直接检查$LASTEXITCODE:
Get-ChildItem -Path . -Filter *.docx | ForEach-Object { pandoc -s $_.FullName -t markdown --extract-media=./media_$($_.BaseName) -o "$($_.BaseName).md" if ($LASTEXITCODE -ne 0) { Write-Host "转换失败: $($_.Name)" -ForegroundColor Red } }7.3 转换后的一致性检查清单
批量转换跑完之后,别急着收工,按这个清单过一遍:
- 检查每个输出目录的图片数量,跟 Word 原文档里的图片数量是否吻合。
- 抽查 3-5 个文件,确认标题层级、表格、公式的转换质量。
- 用编辑器打开几个 Markdown 文件,全局搜索
assets/media路径,确认所有图片引用都能在本机打开。 - 如果发现某份文档有异常,回到原文件检查是不是样式或嵌入方式有问题,修复后重新转换。
批量转换的关键在于“可重复”:转换命令、清理脚本、检查清单都保留下来,下次再来一批文档时,直接用同一套流程跑一遍就行。
8. 我踩过的几个坑,以及最终的实践经验总结
最后分享一些我在真实项目中踩过的坑,每个都是花时间换来的。
8.1 图片文件名乱序:Pandoc 重命名图片的规律
第一次批量转换后,我兴冲冲地预览 Markdown,发现图片张张都在,但顺序不对——文中的第一张截图,落盘文件名居然是image5.png。当时以为是 Pandoc 的问题,后来才发现是 Word 内部图片对象的引用 ID 排列顺序跟视觉顺序不完全一致。
解决方案分两种:如果不在乎文件名,那么在 Markdown 渲染层面,引用顺序是正确的,你看到的效果没问题;如果有强迫症或者需要人工维护图片文件,那就用图片管理工具统一重命名,或者写脚本按出现顺序重新命名。这里我提醒一句:不要试图手改 Pandoc 生成的引用路径,除非你同时改了文件名,否则很容易出现“文字对不上图”的尴尬。
8.2 字体效果保留:粗体、斜体可以,下划线和颜色会丢失
Word 里的加粗、斜体,Pandoc 能准确转成 Markdown 的**和*。但下划线是 Markdown 标准语法里没有的东西,Pandoc 转换时直接把下划线吞掉了。如果你确实需要保留下划线,可以在转换后把对应文本单独替换为 HTML 标签<u>文字</u>,但这种做法在大多数 Markdown 渲染器里也能正常显示,只是没法保证在所有平台统一。
字体颜色、高亮、删除线这类视觉样式,基本不值得刻意保留。原因我之前说过:Markdown 是内容优先的格式,颜色和字号应该交给渲染层去控制。如果有一处文字在 Word 里是红色强调,那么转换时你更应该关注的是它是不是真的需要强调,而不是强行把红色属性带到 Markdown 里。
8.3 “保留 Word 格式”的正确理解:保留结构而不是像素级还原
这个体会我想多说几句。很多朋友问“Word 转 Markdown 能保留格式吗”,我的答案是:能保留的是结构格式,不是视觉效果。标题层级、列表嵌套、表格结构、脚注、公式、图片引用,这些是信息层面的;而字体、字号、行距、缩进、页边距,这些是展示层面的,在 Markdown 里本来就不存在。
理解了这个区别,你对转换结果的期望就不会过高,也不会因为一段文字没有居中对齐就觉得转换失败了。实际上,居中对齐这种需求在 Markdown 里可以用<div align="center">实现,但这属于特例,不是常规操作。
8.4 最省时间的转换工作流分享
把前面所有经验压缩成一套最省时间的流程,大概是这样的:
- 用 Python 或手动,快速检查 docx 的样式使用情况、图片状态、公式类型。
- 在 Word 里统一修复:标题样式、MathType 公式、手动编号。
- 用 Pandoc 批量转换,每个文档单独存放媒体文件。
- 用 VS Code 全局替换图片路径,补 Frontmatter。
- 打开 Typora 或文档站预览,人工过一遍标题层级和复杂表格。
- 有问题就改原文件再转,不要直接改 Markdown。
这套流程我跑了很多次,从最初的一次转换要用一整天,到后来平均每份文档可以控制在十分钟以内,包括清理和检查。真正让我觉得踏实的,不是某个工具多强大,而是每一步都可以被重复、被验证、被修复。Word 转 Markdown 不是什么黑科技,它就是一个“结构化文档 → 另一个结构化文档”的映射过程,理解了源文件的本质,选对工具,剩下的就是耐心和细节了。