从 Markdown 到中文产品文档:一次 Pandoc DOCX 脚手架搭建复盘
哈喽,欢迎来到我的公众号「NG哥学堂」。NgGor是NG哥养的🦞~
在工作中,经常需要将同一份产品材料更换为不同品牌样式的对外资料,效率低下,还不能保证同一品牌的不同文档格式高度一致。为此,最近我在AI的帮助下,构建了一套基于 Pandoc 的 DOCX 生成脚手架,目标很明确:团队用 Markdown 写产品说明书、用户手册、部署手册,最后稳定输出带品牌封面、页眉页脚、目录、表格和中文字体规范的 Word 文档。
一开始我以为这只是”Markdown 转 Word”。真正做下来才发现,难点不是转换,而是中文产品文档的交付细节。
比如:封面要有品牌背景和 logo;正文要宋体 11pt、首行缩进 2 字;目录要层级缩进、页码右对齐;表格要铺满正文区,表头要有品牌色,单元格要上下左右居中。任何一项靠手工调,都不难;但每份文档都调一遍,就会变成持续消耗。
所以这套脚手架的核心,不是让 Word 消失,而是把重复、易错、可规范化的部分自动化。
一、内容和样式分开
正文统一放在 content/*.md。Markdown 只负责文档内容和章节结构:
---title:产品用户手册subtitle:适用对象:客户管理员、运维工程师author:admindate:2026-06-30version:v1.0---:::toc:::# 产品简介
这样写作者不需要理解 Word 样式,也不需要反复调整封面、页眉、表格,只要维护内容本身。
样式则交给品牌目录维护。每个品牌都有自己的:
brands/demo/ brand.yml demo_STYLE_SPEC.md reference.docx
brand.yml 放品牌名、项目名、模板版本等变量;STYLE_SPEC 记录页面、字体、标题、目录、表格、页眉页脚等规范;reference.docx 则负责 Word 样式和品牌封面。
新建品牌时,复制 demo,再重命名样式规格文件即可:
cp -R brands/demo brands/acmemv brands/acme/demo_STYLE_SPEC.md brands/acme/acme_STYLE_SPEC.md
这让”品牌模板”变成可复制、可审查、可维护的资产,而不是散落在某个 Word 文件里的隐性经验。
二、reference.docx 不等于正文母版
Pandoc 的 –reference-doc 很有用,但也容易被误解。
它主要继承 Word 样式、页眉页脚、主题、编号等模板信息,并不会自动把 reference.docx 里的整页封面复制到最终文档。
所以我额外写了封面注入逻辑:构建时把品牌 reference.docx 的第一页复制到最终 DOCX 开头,并把封面上的标题、副标题替换成当前 Markdown 的 title 和 subtitle,再把 author、date、version 插入进去。
这样我们仍然可以用 WPS 或 Word 手工设计封面,放 logo、背景图和装饰元素;同时又能让每份文档自动套用这套封面。
三、为什么需要后处理脚本
理想情况下,Pandoc 加 reference.docx 就该结束了。但实际处理 DOCX 时,还有很多跨编辑器细节。
例如 Markdown 表格转换成 DOCX 后,宽度不一定铺满正文区域,表格边框、单元格对齐、表头底色也不一定稳定继承 Word 表格样式。
于是我增加了 fix_docx_tables.py 作为构建后处理器。用户仍然只运行:
bash scripts/build-docx.sh sample demo
内部流程则是:
Pandoc 生成临时 DOCX注入 reference.docx 封面修正表格、目录、页眉页脚等 DOCX XML输出到 outputs/
这个脚本会统一表格宽度、补齐边框、设置单元格居中,并读取品牌 STYLE_SPEC 中的表头背景色和文字颜色,写入每个 Markdown 表格的第一行。
这一步很关键:品牌色不再依赖 Word 的隐式继承,而是由脚本直接写进最终 DOCX。
四、踩坑最多的是目录
目录看起来简单,实际最容易出问题。
我们希望一级目录左对齐,二级目录缩进,页码右对齐。但 WPS 手动更新目录时,可能会重新生成 toc 1、toc 2 这类样式,并让它们继承正文的首行缩进。正文首行缩进是 2 字,目录一级也跟着缩进,于是左侧就空了一截。
最后的处理方式是:后处理脚本不仅修标准 TOC1/TOC2/TOC3,还要识别 WPS 实际生成的 toc 1/toc 2/toc 3,并保留它们的 styleId,只修缩进和制表位。
如果在 WPS 里手动更新目录后样式又乱了,保存后再执行一次修复脚本即可:
.venv/bin/python scripts/fix_docx_tables.py outputs/文档名-品牌名.docx --style-spec brands/品牌名/品牌名_STYLE_SPEC.md
这件事也提醒我:做 DOCX 自动化,不能只考虑 Pandoc,还要考虑最终编辑器会如何改写文档。
五、把规则沉淀成文档
脚手架最后不只是脚本,还包括几份说明:
-
Quick_Start.md:给新用户快速上手。 -
PANDOC_DOCX_SCAFFOLD_README.md:解释整体结构和构建流程。 -
HARNESS_CODING_RULES.md:约束后续维护方式,避免破坏链路。 -
DEMO_BRAND_README.md:说明 demo 品牌如何复制和改造。
这些文档的价值不低于代码。因为这套东西不是一次性脚本,而是要让团队成员,甚至后续 AI,都能继续维护。
我们还明确了一些边界:当前只保证 DOCX,不默认输出 PDF;不把 Obsidian 写成产线依赖;不提交 outputs/*.docx;品牌样式尽量进 STYLE_SPEC,构建产物尽量由脚本生成。
结语
这次搭建让我最大的感受是:文档工程化不是要消灭 Word,而是让 Word 做它擅长的视觉模板,让 Markdown 做它擅长的内容维护,让脚本处理重复和易错的转换细节。
当内容、样式、品牌、构建、版本管理各归其位,一份产品说明书就不再是”某个人电脑里调好的 Word 文件”,而是一套可以复制、审查和持续维护的交付流程。
附上 Github 链接:https://github.com/JBNg1209/pandoc-docx-scaffold[1]
关注我,一个有趣的公众号,热衷AI潮流 🤖、爱喝咖啡 ☕️
佛系分享 AI 及咖啡资讯,有料有趣。我们下期见!👋
夜雨聆风