一个熟悉的场景:让 AI 写一份方案,三千字两分钟交付,内容大体能用。然后你打开 Word,开始干活。标题层级、字号行距、表格样式、页眉页脚、图表编号,两个小时过去了,文档还没到能发出去的状态。
写作这一环,AI 已经把成本打到接近零;排版这一环,还是纯手工。于是 AI 产出的永远是「半成品」,最后一公里永远要人肉走完。
这篇文章要把这最后一公里拆掉。办法是把 .docx 这个文件拆开,看看里面到底装了什么,而不是去找一个更聪明的 AI。看懂之后你会发现,排版一直要人做,原因在于它一直是个黑盒,它本身并不难。
先说结论:别再让 AI 交 Markdown 让你自己贴进 Word,让它直接交 docx 文件包。门槛最低的做法是你先备一份样式齐全的模板,AI 照常写内容,用 pandoc 一条命令套上模板出成品(文中附一份调好的中文模板,可以直接下载)。后面讲清楚为什么,以及另外两条路。
一、半成品的病根:AI 给的和 Word 要的,是两种东西
先说结论:AI 在聊天窗口里能交付的,本质是一串字符流,最常见的是 Markdown。而一个能被 Word 正常打开的 .docx,是一整套结构化的文件包。从字符流到文件包,中间隔着一次转换,这次转换在大多数人的工作流里是缺位的。于是 Markdown 的 ## 没有变成 Word 的「标题 2」样式,只是一个普通的井号;表格边框、题注编号、页眉页脚更没有着落。丢掉的格式信息,最后全部由人在 Word 里手工补齐。
Markdown 和 docx 之间没有官方血缘。前者是轻量标记,后者是一整套国际标准(下面会讲)。指望「AI 输出 Markdown → 粘贴进 Word → 万事大吉」这条路不出问题,本身就不现实。

所以问题被重新定义成:能不能让 AI 直接产出、或者借助工具组装出那个结构化的文件包?要回答它,先得知道文件包长什么样。
二、docx 是「一包文件」
做个实验。复制一份 docx(务必复制,别拿原件动手),把后缀改成 .zip,解压。装了 7-Zip 或 WinRAR 的可以直接打开,连改名都省了。你会得到这么一堆东西:
解压目录
├─ [Content_Types].xml 登记簿:包内每一类文件是什么类型
├─ _rels/.rels 顶层关系表:告诉程序主文档在哪
├─ docProps/ 元信息:作者、创建时间(core.xml),页数字数(app.xml)
└─ word/ 核心目录,重点全在这
├─ document.xml 正文:每一段、每一句、每个表格
├─ styles.xml 样式定义:标题 1、正文、表格样式长什么样
├─ numbering.xml 自动编号与列表规则
├─ fontTable.xml 字体清单
├─ settings.xml 全局设置:修订、兼容模式
├─ media/ 图片本体:img1.png、img2.jpg 都在这
├─ theme/theme1.xml 主题颜色与字体方案
├─ _rels/document.xml.rels 正文的关系表:图片、页眉、脚注挂在哪里
└─ header1.xml / footer1.xml / footnotes.xml / comments.xml 有对应内容才出现
这套结构叫 OOXML(Office Open XML),标准编号 ECMA-376 / ISO/IEC 29500,从 Office 2007 起取代老的二进制 .doc/.xls/.ppt。Word、Excel、PowerPoint 分别对应三套标记语言:WordprocessingML(.docx)、SpreadsheetML(.xlsx)、PresentationML(.pptx),套路完全一样,xlsx 里是 xl/worksheets/sheet1.xml,pptx 里是 ppt/slides/slide1.xml。下文都拿 Word 举例,换汤不换药。

四个角色值得记住:document.xml 是稿子,styles.xml 是着装规范,关系表和 [Content_Types].xml 是通讯录加登记簿,media/ 是图片仓库。
顺带一提,偶尔听到的 ODF(.odt 那一家)是开源社区主导的另一套标准,和 OOXML 是两回事,本文只讲 OOXML。
比起老的二进制格式,这套设计的卖点当年就讲清楚了:文件更小、损坏了容易修、程序可以直读直写。最后这一条,正是本文的主角。
三、读正文,只要认识三个标签
用浏览器或 Notepad++ 打开 word/document.xml,开头会有一长串 xmlns: 打头的网址,叫命名空间声明,可以理解成「下面这些标签出自哪本字典」,先跳过它。剩下的骨架其实只有三层:
<w:p> <!-- paragraph:段落 -->
<w:r> <!-- run:一段格式相同的连续文字 -->
<w:t>你好,OOXML</w:t> <!-- text:真正的文字 -->
</w:r>
</w:p>

段落自身的格式(对齐方式、行距、套用哪个样式)写在段落开头的 <w:pPr> 里;文字的格式(加粗、颜色、字号)写在 run 开头的 <w:rPr> 里。想加粗「你好」两个字,就是 rPr 里多一个 <w:b/>。所谓排版,在文件层面就是给文字贴标签,这件事 AI 比人擅长。
但有两个认知坑,恰好就是「规范文档」和「毛坯文档」的分水岭。
第一,标题是一种样式,大号加粗的字算不上标题。 规范的做法是段落属性里写 <w:pStyle w:val="Heading1"/>,让这个段落引用 styles.xml 里的「标题 1」样式。区别在语义,外观倒在其次:套了样式的标题会进导航窗格、自动目录、交叉引用;手动放大字号做出的「假标题」在这些地方全部隐身。而且全文样式一改,真标题跟着变,假标题原地不动。你交出去的文档被批「不规范」,多半栽在这里。

这里有个细节特别容易踩。Heading1 是英文版 Word 给「标题 1」起的样式 ID,中文版 Word 存出来的文档里,这个 ID 经常就是一个数字 1。引用的 ID 在 styles.xml 里找不到,Word 也不报错,标题会悄悄退回成普通正文。所以让 AI 写代码或直接写 XML 之前(第四节的路线二、三),先解压模板,到 styles.xml 里看一眼每个样式真实的 w:styleId,再把这些 ID 告诉 AI。
第二,格式数字有自己的单位,跟日常说的「磅」对不上。 第一次打开 XML,你会看到小四写成 24、单倍行距写成 240,像是对不上号。原因是 Word 存格式时不用小数,于是给每类数字配了一把自己的尺子:

- 字号
w:sz用半磅。 磅数乘以 2,五号字的 10.5 磅就能存成整数 21。 - 行距
w:line按倍数设置时,一整行记作 240。 单倍是 240,1.5 倍是 360。 - 纸张和页边距用 twip。 1 twip 是 1/20 磅,1 厘米约等于 567 twip。
常用的值整理成一张表,写提示词时可以直接查:
| 日常说法 | Word 里写 | 怎么算的 |
|---|---|---|
| 五号字(10.5 磅) | w:sz="21" |
10.5 × 2 |
| 小四(12 磅) | w:sz="24" |
12 × 2 |
| 四号(14 磅) | w:sz="28" |
14 × 2 |
| 三号(16 磅) | w:sz="32" |
16 × 2 |
| 单倍行距 | w:line="240" |
1 × 240 |
| 1.5 倍行距 | w:line="360" |
1.5 × 240 |
| 固定值 28 磅 | w:line="560",w:lineRule="exact" |
28 × 20,单位换成了 twip |
| A4 纸宽、高 | 11906、16838 |
21 厘米、29.7 厘米,各乘约 567 |
| 页边距 2.54 厘米 | 1440 |
正好 1 英寸 |
留意固定值那一行:同一个 w:line,lineRule 一换,单位就从「行的 1/240」变成了 twip。这类细节人很难记住,交给 AI 却正合适。格式能被精确到个位数的数字描述,这正是「AI 能精确执行」的前提。
还有件事经常让人意外:图片不在 document.xml 里。正文里只有一个带 r:embed="rId5" 的引用,顺着 word/_rels/document.xml.rels 查这个 ID,才指向 media/ 文件夹里的 img1.png。内容和资源永远分离,靠关系表缝合。这也是为什么「解压 docx 抢救图片」是个真实可行的操作。
四、原理清楚之后,半成品问题怎么解
回到开头的问题:从字符流到文件包的那次转换,谁来补?
XML 本身就是文本,而 AI 最擅长生成文本。一个最小可用的 docx 只需要三个文件:
mini/
├─ [Content_Types].xml
├─ _rels/.rels
└─ word/document.xml
前两个文件的内容是固定的,照抄就行。[Content_Types].xml 登记文件类型:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Types xmlns="http://schemas.openxmlformats.org/package/2006/content-types">
<Default Extension="rels" ContentType="application/vnd.openxmlformats-package.relationships+xml"/>
<Default Extension="xml" ContentType="application/xml"/>
<Override PartName="/word/document.xml" ContentType="application/vnd.openxmlformats-officedocument.wordprocessingml.document.main+xml"/>
</Types>
_rels/.rels 告诉 Word 正文在哪:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<Relationships xmlns="http://schemas.openxmlformats.org/package/2006/relationships">
<Relationship Id="rId1" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/officeDocument" Target="word/document.xml"/>
</Relationships>
document.xml 才是你要写的正文,最小内容是这样:
<?xml version="1.0" encoding="UTF-8" standalone="yes"?>
<w:document xmlns:w="http://schemas.openxmlformats.org/wordprocessingml/2006/main">
<w:body>
<w:p>
<w:r>
<w:t>Hello OOXML</w:t>
</w:r>
</w:p>
<w:sectPr/>
</w:body>
</w:document>
三个文件齐了,进 mini 目录把这三项打包成 zip,后缀改成 .docx,Word 就能打开(这三个文件我在 Word 和 LibreOffice 里都实测过)。注意压缩包根目录必须直接是它们,外面不能再套一层文件夹。这件事本身证明:docx 完全可以被「写」出来,不需要经过 Word。不过这个最小包里没有 styles.xml,只能放纯文字;想用标题样式,就得把定义了这些样式的 styles.xml 一起带上。
由此得到三条路线,按技术门槛从低到高排:不写代码、写代码调库、直接手写 XML。

路线一:模板填充。人定规范,AI 填内容。 先准备一份样式齐全的 docx 模板,标题层级、正文样式、表格样式、页面和页码全部定义好,然后让 AI 只管内容,再用工具把内容灌进模板。灌的工具有两种,都不用自己写代码。
一种是 pandoc。AI 照常写 Markdown,一条命令套上你的模板:
pandoc 方案.md -o 方案.docx --reference-doc=中文方案模板.docx --shift-heading-level-by=-1
pandoc 会把 Markdown 的标题映射成 Word 里真正的标题样式,样式的长相沿用模板里的定义。第一节说的那次缺位的转换,它一步就补上了。最后那个参数让第一个 # 变成居中的文档标题,## 对应「标题 1」,符合中文方案「大标题下面分一、二、三」的习惯;不加的话,文档主标题和「一、项目背景」会长得一模一样。

模板有个坑,我实测时才撞上:别拿手头随便一份「样式齐全」的 docx 直接当模板。pandoc 生成的表格用的是一个名叫 Table 的样式,不是你调好的「网格型」;正文用的是「正文文本」和「首段」两个样式,段前段后间距也是 pandoc 自己的。拿现成文档直接套,表格多半只剩表头下面一条线。稳妥的做法是先导出 pandoc 自带的模板,再改它真正会用到的那几个样式:
pandoc -o 模板.docx --print-default-data-file reference.docx
在 Word 里打开导出的文件,到样式窗格改标题 1 至标题 3、正文文本、首段、Compact(表格单元格和紧凑列表用)和 Table 这几项,存盘就是你的模板。标题这边倒不用操心:pandoc 按样式名认标题,中文版 Word 把「标题 1」的 ID 存成 1 也能对上(pandoc 3.9 实测),第三节说的「先查真实 ID」只在后两条路线里需要。
嫌麻烦可以直接用我调好的一份:正文宋体小四、1.5 倍行距、首行缩进两字,三级标题依次是黑体三号、四号、小四,表格全框线加灰底表头,A4 纸、Word「普通」页边距,页脚居中页码。下载中文方案模板。单位对字体字号另有要求的,在样式窗格里改对应那一项就行。
另一种是 docxtpl,适合合同、标书这类版式完全固定、只在固定位置填字段的文档:在模板里埋好占位符,AI 只产出字段值。
人的投入是一次性的,之后每份文档的格式都由模板兜底。你想要的格式,就是你定义的样式表,这是「让文档符合自己要求」最直接的杠杆。
路线二:AI 写代码调库。 python-docx、openpyxl、python-pptx 这些库,本质是替你组装上面那堆 XML:闭合标签、关系表、Content_Types 都由库保证不出错。让 AI 写代码调库,比让它直接手写 XML 稳得多,适合复杂结构,比如从数据批量生成表格、带图表的分析报告、一次产出几十份个性化文档。
路线三:AI 直写 XML。 极端定制场景,比如要 Word 原生修订(tracked changes),或者库没覆盖的冷门特性,可以让 AI 直接产出 document.xml 再打包。能力上限最高,风险也最高:少一个闭合标签,Word 当场报「文件损坏」。
这条路已经有人走通了。开源 AI 办公套件 GenOffice,底层就是这套原理:改哪块只重写哪块的 XML,没动的部分逐字节保留,改完的文件在 Word 里照常打开。所谓「AI 原生办公」,拆到文件层,就是让 AI 直接操作 OOXML。
自己想走这条路又不想从零写,可以装现成的 skill。Anthropic 官方的 docx skill(anthropics/skills,在 Claude Code 里先执行 /plugin marketplace add anthropics/skills,再执行 /plugin install document-skills@anthropic-agent-skills)把「解包、改 XML、打包」做成了现成脚本,打包时按 OOXML 的 schema 校验并自动修复,标签没闭合这类错误在交付前就被拦下,也不会出现根目录多套一层的问题;它还能写 Word 原生的修订和批注。MiniMax 开源的 minimax-docx(MiniMax-AI/skills,MIT 协议)基于 .NET 的 OpenXML SDK,参照 GB/T 9704 内置了公文版式,同样要过 schema 校验才交付。上面那份中文模板做完后,我就是拿前一个的校验脚本查的。
不管走哪条路,提示词都要跟着升级。走路线一时,格式全在模板里,AI 只需交一份干净的 Markdown,提示词一句话就够:
用一个 # 写文档标题,## 写「一、二、三」,### 写「(一)(二)」;表格用标准 Markdown 表格;不要手动加粗或改字号,格式交给模板。
走路线二、三时,「帮我排个版」这种说法 AI 只能靠猜;把格式要求翻译成上面讲的词汇,它就能精确执行。下面这段可以直接改了用:
请按以下规范生成 Word 文档:
- 一级标题套用样式 ID 为 1 的样式,二级标题套用样式 ID 为 2 的样式(先确认模板 styles.xml 里的真实 ID)
- 正文宋体小四,w:sz=24;行距 1.5 倍,w:line=360,lineRule=auto
- 表格套用「网格型」样式(英文版 Word 里叫 Table Grid)
- 页面 A4,上下左右页边距各 2.54 厘米(1440 twip)
- 不要用手动加粗放大来做标题
能说清楚的格式,才是不用返工的格式。
五、打包踩坑清单
实操环节最容易翻车的地方,一次列全:
- zip 根目录多套了一层文件夹。这是「明明有文件却报损坏」的第一大原因,打包时一定进到内容目录里选中那几项再压缩。
- XML 标签没闭合,或中文内容没按 UTF-8 编码保存。
- 命名空间声明 xmlns:w 被删掉,所有标签失效。
- body 末尾建议保留
<w:sectPr>。它不是必需项,缺了 Word 照样能打开,但纸张大小、页边距会全部走 Word 的默认值;想要 A4 和自定义页边距,就得写在这里。 - 引用的样式 ID 在 styles.xml 里不存在。Word 不报错,只是悄悄按普通正文显示,最难发现。
- .docm(带宏的文档)解压后还有 VBA 宏文件,重新打包时别漏。
- 永远在副本上动手,原件别碰。
改坏了也不必慌。XML 是纯文本,哪里错了打开就能看到。
六、文档即数据
把 docx 拆开看懂之后,「排版」的性质变了。它从藏在 Word 菜单里的手艺,变成了一份可以完整写下来的数据。凡是可以完整写下来的,就可以完整交给 AI。
人的位置随之上移:从排版工,变成规范制定者。你定义样式表、准备模板、把格式要求说成 AI 听得懂的语言;内容的生成和格式的执行,交给机器。内容的生产成本已经被打到地板上,格式的生产成本也可以,前提是你得知道那个文件里装的是什么。
下一篇已经写完。第三条路线「AI 直写 XML」已经有人做成了现成工具,我拆了开源 AI 办公套件 GenOffice,它怎么让 Claude Code、Codex 这类智能体直接交付真 Office 文件,哪些原本要开会员的 PDF 动作可以免费做,以及该不该装。见《AI 智能体终于能直接交 Word 和 PPT 了,这个免费开源的 Office 该不该装》。
评论