如何让python-docx生成的Word文档各章节步骤编号重新开始?
解决SOP文档章节步骤编号不重置问题
问题分析
生成SOP Word文档时,各章节的步骤编号会延续上一章节的计数(如第一章步骤为1、2,第二章直接从3开始),原因是所有章节共享同一个全局编号序列,计数器未在新章节起始时重置。
解决方案
使用python-docx库时,为每个章节创建独立的编号序列,确保每个章节的步骤编号从1开始计数。以下是完整实现代码:
1. 依赖库导入
from docx import Document from docx.enum.text import WD_PARAGRAPH_ALIGNMENT from docx.oxml.ns import qn from docx.oxml import OxmlElement
2. 修正后的build_doc函数
def build_doc(sop_data, output_path): doc = Document() for chapter in sop_data['chapters']: # 添加章节标题 heading = doc.add_heading(chapter['title'], level=1) heading.alignment = WD_PARAGRAPH_ALIGNMENT.CENTER # 为当前章节创建独立的编号序列 numbering_part = doc.part.numbering_part num = numbering_part.add_num() # 配置编号规则:起始值1、十进制格式、显示为"1." lvl = num.add_lvl(ilvl=0) lvl.start = OxmlElement('w:start') lvl.start.set(qn('w:val'), '1') lvl.num_fmt = OxmlElement('w:numFmt') lvl.num_fmt.set(qn('w:val'), 'decimal') lvl.lvl_text = OxmlElement('w:lvlText') lvl.lvl_text.set(qn('w:val'), '%1.') lvl.lvl_jc = OxmlElement('w:lvlJc') lvl.lvl_jc.set(qn('w:val'), 'left') # 设置段落缩进(可选,优化排版) lvl.p_pr = OxmlElement('w:pPr') ind = OxmlElement('w:ind') ind.set(qn('w:left'), '720') ind.set(qn('w:hanging'), '360') lvl.p_pr.append(ind) # 获取当前编号序列ID num_id = num.numId # 添加章节步骤 for step in chapter['steps']: para = doc.add_paragraph() # 绑定当前段落到新的编号序列 num_pr = para._p.get_or_add_pPr().get_or_add_numPr() num_pr.get_or_add_numId().val = num_id num_pr.get_or_add_ilvl().val = 0 para.text = step doc.save(output_path)
3. 测试用JSON数据示例
{ "chapters": [ { "title": "设备开机检查", "steps": [ "检查电源连接是否牢固", "确认设备开关处于关闭状态", "按下电源按钮启动设备" ] }, { "title": "日常维护流程", "steps": [ "清洁设备表面灰尘", "检查耗材剩余量", "记录维护日志" ] } ] }
4. 函数调用示例
import json # 加载JSON数据 with open('sop_data.json', 'r', encoding='utf-8') as f: sop_data = json.load(f) # 生成SOP文档 build_doc(sop_data, 'SOP标准作业程序.docx')
关键说明
- 为每个章节创建独立的编号序列,而非全局共享一个序列,确保计数器在新章节重置为1。
- 通过直接操作OXML元素实现编号配置,弥补
python-docx高层API对编号控制的局限性。
内容的提问来源于stack exchange,提问作者Liz W.




