生成操作手册时,步骤必须带编号;整理需求清单时,条目通常用圆点;而在规格说明里,条目往往要分成"1. 概述 / 1.1 背景 / 1.1.1 范围"这样的多级结构。手工在 Word 里操作并不难,点一下编号按钮即可,但当文档由脚本批量生成、或者每次导出的内容条目数量不固定时,逐个点击就不现实了。
Word 的列表并不是简单的文本前缀,而是一套由"列表样式 + 段落列表格式"组成的结构。理解了这两层,就能用 Python 生成任意层级、任意起始编号的列表。本文介绍用 Spire.Doc for Python 在 Word 文档中创建编号列表、项目符号列表,以及控制多级编号和重新开始编号的方法。
为什么用脚本处理列表
- 结构稳定:编号由样式驱动,增删条目后序号自动重排,不需要手工修正。
- 多级一致:层级通过
ListLevelNumber指定,不会出现某一级缩进不一致的问题。 - 可批量:同一套列表样式可以套用到多份文档,条目内容由数据决定。
环境准备
安装 Spire.Doc:
pip install Spire.Doc
在脚本中导入需要的模块:
from spire.doc import *
from spire.doc.common import *
列表格式的两层结构
Spire.Doc 把列表拆成两层:
- 列表样式(
ListStyle):定义编号的外观,包括每一级的编号格式、前缀、起始值和符号字符。通过document.Styles.Add(ListType.Numbered, "名称")创建。 - 段落列表格式(
ListFormat):把样式应用到具体段落,并指定该段落属于第几级。通过paragraph.ListFormat.ApplyStyle("名称")和ListLevelNumber设置。
样式只需要定义一次,之后每个段落调用 ApplyStyle() 即可接入同一套编号序列。
应用内置编号样式
如果只需要最简单的连续编号,ApplyNumberedStyle() 一步就能完成:
from spire.doc import *
from spire.doc.common import *
document = Document()
section = document.AddSection()
items = ["Set up the environment", "Install the library", "Run the first script"]
first = True
for item in items:
paragraph = section.AddParagraph()
paragraph.AppendText(item)
if first:
paragraph.ListFormat.ApplyNumberedStyle()
first = False
else:
paragraph.ListFormat.ContinueListNumbering()
document.SaveToFile("SimpleNumberedList.docx", FileFormat.Docx2013)
document.Close()
这里有两个关键点:第一段用 ApplyNumberedStyle() 创建列表并开启编号;后续段落调用 ContinueListNumbering() 表示"接着上一个编号往下排"。如果每一段都调用 ApplyNumberedStyle(),得到的是若干个各自从 1 开始的新列表。
创建自定义编号样式
需要控制编号格式(例如"1."或"1.1.")时,就要创建独立的列表样式。样式的每一级都在 ListRef.Levels 中配置:
from spire.doc import *
from spire.doc.common import *
document = Document()
section = document.AddSection()
# 创建编号列表样式
numberList = document.Styles.Add(ListType.Numbered, "numberList")
levels = numberList.ListRef.Levels
# %1 ~ %9 是各级编号的占位符
levels[0].NumberPrefix = "%1."
levels[0].PatternType = ListPatternType.Arabic
levels[1].NumberPrefix = "%1.%2."
levels[1].PatternType = ListPatternType.Arabic
levels[2].NumberPrefix = "%1.%2.%3."
levels[2].PatternType = ListPatternType.Arabic
# 添加三个层级的段落
for text, level in [("Overview", 0), ("Background", 1), ("Scope", 2)]:
paragraph = section.AddParagraph()
paragraph.AppendText(text)
paragraph.ListFormat.ApplyStyle(numberList.Name)
paragraph.ListFormat.ListLevelNumber = level
document.SaveToFile("CustomNumberedList.docx", FileFormat.Docx2013)
document.Close()
NumberPrefix 中的 %1、%2、%3 分别代表第 1、2、3 级的计数器,所以二级写 %1.%2.、三级写 %1.%2.%3.,就能得到"1.1."和"1.1.1."的效果。PatternType = ListPatternType.Arabic 指定使用阿拉伯数字,枚举中还有其他数字形态可选。
ListLevelNumber 从 0 开始:0 表示第一级,1 表示第二级,依此类推。这一点容易与 Levels 的下标混淆,但两者是一致的,都从 0 起算。
项目符号列表
项目符号的创建方式与编号列表相同,只是把类型换成 ListType.Bulleted:
from spire.doc import *
from spire.doc.common import *
document = Document()
section = document.AddSection()
# 创建项目符号样式
bulletList = document.Styles.Add(ListType.Bulleted, "bulletList")
items = ["Reusable template", "Batch output", "Consistent formatting"]
for item in items:
paragraph = section.AddParagraph()
paragraph.AppendText(item)
paragraph.ListFormat.ApplyStyle(bulletList.Name)
document.SaveToFile("BulletedList.docx", FileFormat.Docx2013)
document.Close()
如果需要自定义符号形状,可以修改每一级的 BulletCharacter。Word 的项目符号本质上是一个字符,只要指定一个能映射出图形的字符并配上对应字体即可:
# 使用 Wingdings 字体中的字符作为项目符号
bulletList = document.Styles.Add(ListType.Bulleted, "squareBullet")
levels = bulletList.ListRef.Levels
levels[0].BulletCharacter = "\u006e"
levels[0].CharacterFormat.FontName = "Wingdings"
\u006e 在 Wingdings 字体中渲染为实心方块;换成 \u0075、\u00b2、\u00d8 等字符会得到其他符号。关键在于 CharacterFormat.FontName 必须与字符所属的符号字体一致,否则显示为空白或问号。
让新列表从指定数字开始
有时第二组清单需要接着编号规则往下排,或者故意从某个数字开始。此时不必新建两套样式,直接设置起始值即可:
from spire.doc import *
from spire.doc.common import *
document = Document()
section = document.AddSection()
numberList = document.Styles.Add(ListType.Numbered, "Numbered1")
for text in ["List Item 1", "List Item 2"]:
paragraph = section.AddParagraph()
paragraph.AppendText(text)
paragraph.ListFormat.ApplyStyle(numberList.Name)
# 第二套列表从 10 开始
numberList2 = document.Styles.Add(ListType.Numbered, "Numbered2")
numberList2.ListRef.Levels[0].StartAt = 10
for text in ["List Item 3", "List Item 4"]:
paragraph = section.AddParagraph()
paragraph.AppendText(text)
paragraph.ListFormat.ApplyStyle(numberList2.Name)
document.SaveToFile("RestartList.docx", FileFormat.Docx2013)
document.Close()
StartAt 作用于指定级别,设置在第一级上表示整个序号从该数字起算。如果希望两套列表属于同一序列、只是中间断开了,用前面提到的 ContinueListNumbering() 更合适;StartAt 则适用于"重新开始并指定起点"的场景。
实用建议
- 先建样式再写段落:
Styles.Add()只需调用一次,后续段落都通过ApplyStyle()复用同一样式。 - 层级用 0 起算:
ListLevelNumber与Levels下标一致,写错一级会让缩进和编号前缀同时错位。 ApplyNumberedStyle()与ApplyStyle()不要混用:前者自带一套内置编号,后者引用自定义样式,在同一组段落中混用会打断编号序列。- 符号字体要匹配:自定义
BulletCharacter时必须同时设置FontName,并在目标环境中确认该字体可用。 - 释放资源:保存后调用
document.Close();批量生成时逐个创建、保存、关闭,避免内存累积。
结语
本文介绍了使用 Python 在 Word 文档中创建列表的几种方式:用 ApplyNumberedStyle() 快速生成连续编号,通过 Styles.Add(ListType.Numbered, ...) 配合 Levels[i].NumberPrefix 定义多级编号格式,用 ListType.Bulleted 与 BulletCharacter 生成自定义项目符号,以及用 ContinueListNumbering() 和 StartAt 控制编号的延续与重启。由于编号由样式统一驱动,条目数量变化时序号会自动调整,适合放进模板化的文档生成流程。