基于 Word 模板样式生成文档
适用场景
用户提供一个 .docx 模板,要求按模板的排版/标题格式生成一篇新文档(常见:工程交底、工程概况、报告类,含图、表、三级标题结构)。
核心原则
- 样式保真:不新建样式,直接复用模板内置样式(Heading 1-3、Normal、图名、表名、表格等)。
- 自动编号去重:先检查模板样式是否绑定多级编号,绑定了就绝不在标题/图表题文字里手写编号(否则出现"1.1 1.1"重复)。
- 可重复生成:写一个 build_doc.py 脚本,改内容后一键重出文档。
工作流程
第一步:解析模板(必做)
用 python-docx 检查三类信息:
import docx
from docx.oxml.ns import qn
d = docx.Document(模板路径)
# 1) 段落与样式清单(哪些样式被实际使用)
# 2) 各样式字体字号:styles['Heading 1'].font、paragraph_format
# 3) 关键:样式是否绑定自动编号
for name in ['Heading 1','Heading 2','Heading 3','图名','表名']:
pPr = d.styles[name].element.find(qn('w:pPr'))
n = pPr.find(qn('w:numPr')) if pPr is not None else None
# 记录 ilvl + numId
再查 numbering.xml 中对应 abstractNum 各级 w:lvlText,确认编号格式:
- 标题级常见:%1 / %1.%2 / %1.%2.%3
- 图名/表名常见:图 %1.%2.%6 / 表 %1.%5(按章节自动编号)
第二步:生成文档骨架脚本
from docx import Document
from docx.shared import Pt, Cm
d = Document(模板路径)
body = d.element.body # 清空正文但保留节属性和样式定义
for child in list(body):
if child.tag != qn('w:sectPr'):
body.remove(child)
工具函数:
- h(text, level):d.add_paragraph(text, style=f'Heading {level}'),text 不带任何手写编号
- para(text):Normal + 首行缩进 2 字符(Pt(24))
- caption(text):样式"图名"、居中、run 加粗
- table_caption(text):样式"表名"、run 加粗
- add_table(rows, widths):style='Table Grid',单元格段落套"表格"样式,表头加粗,居中对齐
第三步:图表编号加粗(自动编号部分)
编号显示格式由 numbering lvl 的 rPr + 段落标记 rPr 共同决定。模板 lvl 若未加粗,或样式覆盖导致不加粗,在图题/表题段落上补:
from docx.oxml import OxmlElement
def bold_para_mark(p):
pPr = p._p.get_or_add_pPr()
rPr = pPr.find(qn('w:rPr'))
if rPr is None:
rPr = OxmlElement('w:rPr'); pPr.append(rPr)
if rPr.find(qn('w:b')) is None:
rPr.append(OxmlElement('w:b'))
在 caption / table_caption 中调用。
第四步:配图
用 ImageGen 生成工程效果图(约消耗 5-10 积分,需告知用户),prompt 要写明结构类型+视角+风格(如"连续钢箱梁大桥正视侧面视角,工程摄影风格")。插入:
pic = d.add_paragraph(); pic.alignment = WD_ALIGN_PARAGRAPH.CENTER
pic.add_run().add_picture(图路径, width=Cm(14.5))
caption('XXX效果图') # 不写"图1"
第五步:校验(生成后必做)
d2 = Document(输出路径)
# 1) 标题/图表题文字中不得残留手工编号:re.search(r'[图表]\s?\d', p.text)、r'^\d+(\.\d+)+'
# 2) 结构核对:inline_shapes 数量、tables 数量、各级标题树
# 3) 字数统计(区分正文/标题),按用户要求控制(±20% 内)
正文引用写法
因编号是自动的,正文引用写"见下图/见下表",不写"见图1/见表2",避免编号对不上。
常见坑
- 重复编号:模板绑定自动编号时手写"一、/1.1/1.1.1/图1/表1"必然重复——全部删掉。
- 编号不加粗:给 run 加粗只影响题名文字,编号需设置段落标记 rPr 加粗(见第三步)。
- editor_sdk/tencent-local-office-edit 降级:open_file 成功但 doc_* 工具报 "document is not open"(流式打开未完成,中英文路径均可能复现)时,直接降级 python-docx 基于模板副本重建,需先告知用户。
- 清空模板时保留 sectPr,否则页面设置(纸张、页边距)丢失。
- python-docx 安装:若隔离环境没有,用
versions/3.13.12/python.exe -m pip install python-docx。 - Windows 下运行 python 脚本加
-X utf8,避免中文输出乱码。
参考脚本
scripts/build_doc.py.template —— 完整可改造的生成脚本模板(含全部工具函数)。