AI 生成内容秒变标准公文!基于 Pandoc + WPS JS 脚本的自动化工作流
前言:AI 写作后的“最后一公里”
随着 LLM(大语言模型)的普及,撰写公文初稿的时间从几小时缩短到了几秒。然而,真正的痛点在于:AI 给出的 Markdown 格式,如何快速变成符合 GB/T 9704《党政机关公文格式》的标准 Word 文档?
手动调整字体(方正仿宋)、字号(三号)、行间距(28-30磅)、首行缩进、以及处理 Pandoc 转换后令人头疼的“软回车”问题,往往又把省下的时间耗了回去。
今天,我分享一套全自动工作流:通过 Markdown → Lua 过滤器 → Pandoc → WPS JS 脚本,实现一键生成完美公文。
一、 核心痛点
在尝试将 Markdown 转为公文 Docx 时,我们通常会遇到三个“深坑”:
- 软回车(LineBreak)问题:Markdown 中的换行在 Word 中常被识别为
^l,导致段落缩进失效。 - 样式丢失:普通转换无法自动应用“方正小标宋”或特定的行间距。
- 列表解析:公文中的有序列表(1. 2. 3.)需要作为普通段落排版,而 Pandoc 默认会将其转化为 Word 的列表控件,格式难以统一。
二、 技术思路:三位一体自动化
为了解决上述问题,我们构建了一个三层过滤体系:
- Lua Filter (Pandoc层):在转换阶段拦截 AST(抽象语法树),将软回车强制转为物理段落,并将有序列表“平铺”为普通文本。
- Reference Doc (模板层):利用 Pandoc 的
--reference-doc功能,预设基础样式。 - WPS JS Macro (排版层):通过 WPS 内置的 JavaScript 宏,一键微调页面边距、字体、固定行高和标题样式。
三、 实战步骤
1. 编写 Lua 过滤器:解决回车与列表问题
创建一个名为 gov_format.lua 的文件。这段脚本会处理 Pandoc 转换逻辑:
-- 处理段落:将软换行拆分为独立段落,解决缩进失效问题
function Para(el)
local res = pandoc.List:new()
local current_content = pandoc.List:new()
for _, inline in ipairs(el.content) do
if inline.t == 'LineBreak' then
res:insert(pandoc.Para(current_content))
current_content = pandoc.List:new()
else
current_content:insert(inline)
end
end
res:insert(pandoc.Para(current_content))
return res
end
-- 处理有序列表:转换为带编号的普通段落,便于公文排版
function OrderedList(el)
local result = {}
for i, item in ipairs(el.content) do
local index = el.start + i - 1
local prefix = index .. ". "
local content = item[1].content
table.insert(content, 1, pandoc.Str(prefix))
table.insert(result, pandoc.Para(content))
end
return result
end
2. 生成并配置基础模板
首先,导出 Pandoc 的默认样式参考文件:
pandoc -o gov-template.docx --print-default-data-file reference.docx
3. 使用 WPS JavaScript 宏进行样式初始化
在 WPS 中打开 gov-template.docx,点击“开发工具”->“JS宏”,粘贴以下代码并运行。它会自动设置公文的标准边距、仿宋字体和 30 磅固定行距。
function 公文样式初始化() {
var doc = ActiveDocument;
// 1. 设置页面边距
var pageSetup = doc.PageSetup;
pageSetup.TopMargin = 105; // 3.7cm ≈ 105磅
pageSetup.BottomMargin = 99; // 3.5cm ≈ 99磅
pageSetup.LeftMargin = 79; // 2.8cm ≈ 79磅
pageSetup.RightMargin = 74; // 2.6cm ≈ 74磅
// 2. 定义需要处理的样式列表
var 所有样式 = [
"标题", "标题 1", "标题 2", "标题 3", "标题 4", "标题 5",
"标题 6", "标题 7", "标题 8", "标题 9", "正文", "正文文本",
"副标题", "日期", "文本块", "Abstract", "Author", "Compact",
"Definition", "Definition Term", "First Paragraph",
"Image Caption", "Table Caption"
];
// 3. 批量设置所有样式的基础属性
for (var i = 0; i < 所有样式.length; i++) {
var 样式名称 = 所有样式[i];
try {
var style = doc.Styles(样式名称);
// 设置字体大小:三号(16磅)
style.Font.Size = 16;
style.Font.Color = 0; // 黑色
// 设置行距:固定值30磅
style.ParagraphFormat.LineSpacingRule = 3; // 3 = 固定值
style.ParagraphFormat.LineSpacing = 30;
// 间距前后为0
style.ParagraphFormat.SpaceBefore = 0;
style.ParagraphFormat.SpaceAfter = 0;
// 设置首行缩进:2字符(约32磅)
style.ParagraphFormat.FirstLineIndent = 32;
// 设置字体:方正仿宋_GBK,三号(16磅)
style.Font.Name = "方正仿宋_GBK";
style.Font.Size = 16;
// 标题类的都不用斜体
if (样式名称.startsWith("标题")) {
style.Font.Italic = 0;
}
} catch (e) {
// 样式不存在则跳过
}
}
// 4. 设置特定样式的特殊属性
// 标题1:方正小标宋_GBK,居中,二号
try {
var style = doc.Styles("标题 1");
style.Font.Name = "方正小标宋_GBK";
style.ParagraphFormat.Alignment = 1; // 1 = 居中
style.Font.Size = 22;
} catch (e) { }
// 标题2:方正黑体_GBK
try {
var style = doc.Styles("标题 2");
style.Font.Name = "方正黑体_GBK";
} catch (e) { }
// 标题3:方正楷体_GBK
try {
var style = doc.Styles("标题 3");
style.Font.Name = "方正楷体_GBK";
} catch (e) { }
console.log("样式初始化完成。");
}
4. 执行最终转换命令
万事俱备,使用以下命令行将你的 AI 初稿 input.md 转换为标准公文:
pandoc -t docx \
--reference-doc gov-template.docx \
--lua-filter gov_format.lua \
-s input.md -o output.docx \
-f markdown+hard_line_breaks
四、 调试方法:如何查看转换过程?
如果格式不符合预期,你可以通过查看 Pandoc 的 AST(抽象语法树) 来定位是 Markdown 语法问题还是 Lua 脚本逻辑问题:
# 查看原始 AST 结构
pandoc input.md -t native
五、 小结
通过这套工作流,你可以实现:
- 输入:一段由 Deepseek/Qwen 生成的 Markdown。
- 过程:自动化脚本处理格式、间距、字体、边距。
- 输出:一份符合公文排版规范的
.docx文件。
这不仅是技术的组合,更是生产力的解放。希望这篇教程能帮到需要频繁处理公文的小伙伴!
标签:#AI写作 #Pandoc #WPS脚本 #公文格式 #自动化办公 #Markdown转换
897

被折叠的 条评论
为什么被折叠?



