如何使用 Python 在 Word 文档中创建和格式化列表

生成操作手册时,步骤必须带编号;整理需求清单时,条目通常用圆点;而在规格说明里,条目往往要分成"1. 概述 / 1.1 背景 / 1.1.1 范围"这样的多级结构。手工在 Word 里操作并不难,点一下编号按钮即可,但当文档由脚本批量生成、或者每次导出的内容条目数量不固定时,逐个点击就不现实了。

Word 的列表并不是简单的文本前缀,而是一套由"列表样式 + 段落列表格式"组成的结构。理解了这两层,就能用 Python 生成任意层级、任意起始编号的列表。本文介绍用 Spire.Doc for Python 在 Word 文档中创建编号列表、项目符号列表,以及控制多级编号和重新开始编号的方法。

为什么用脚本处理列表

  • 结构稳定:编号由样式驱动,增删条目后序号自动重排,不需要手工修正。
  • 多级一致 :层级通过 ListLevelNumber 指定,不会出现某一级缩进不一致的问题。
  • 可批量:同一套列表样式可以套用到多份文档,条目内容由数据决定。

环境准备

安装 Spire.Doc:

bash 复制代码
pip install Spire.Doc

在脚本中导入需要的模块:

python 复制代码
from spire.doc import *
from spire.doc.common import *

列表格式的两层结构

Spire.Doc 把列表拆成两层:

  • 列表样式(ListStyle) :定义编号的外观,包括每一级的编号格式、前缀、起始值和符号字符。通过 document.Styles.Add(ListType.Numbered, "名称") 创建。
  • 段落列表格式(ListFormat) :把样式应用到具体段落,并指定该段落属于第几级。通过 paragraph.ListFormat.ApplyStyle("名称") 和 ListLevelNumber 设置。

样式只需要定义一次,之后每个段落调用 ApplyStyle() 即可接入同一套编号序列。

应用内置编号样式

如果只需要最简单的连续编号,ApplyNumberedStyle() 一步就能完成:

python 复制代码
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 中配置:

python 复制代码
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:

python 复制代码
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 的项目符号本质上是一个字符,只要指定一个能映射出图形的字符并配上对应字体即可:

python 复制代码
# 使用 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 必须与字符所属的符号字体一致,否则显示为空白或问号。

让新列表从指定数字开始

有时第二组清单需要接着编号规则往下排,或者故意从某个数字开始。此时不必新建两套样式,直接设置起始值即可:

python 复制代码
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 控制编号的延续与重启。由于编号由样式统一驱动,条目数量变化时序号会自动调整,适合放进模板化的文档生成流程。

相关推荐
摇滚侠1 小时前
《Java并发编程之美》第 4 章 Java 并发包中原子操作类原理剖析 阅读笔记 7
java·笔记·python
旋律4141 小时前
同义方法区别(增加类与删除类)
java·后端
调试人生的显微镜1 小时前
跨平台抓包工具怎么选?TraceEagle抓包鹰 的四种跨平台能力
后端·ios
羡林i1 小时前
ProcessPoolExecutor 传参踩坑实测:pickle 失败的四种写法
python
用户7771298509122 小时前
常见的同义方法的区别:增加类和删除类
java·后端
房西杭2 小时前
行会仓库 GuildStoreMgr(Lua,和 StoreMgr / BagMgr 容器接口对齐)
后端
Dmz丶2 小时前
前端转 AI 100 天 Day 30:正式上线——从零部署一个完整服务(含 30 天复盘)
python
站大爷IP2 小时前
Python的文本IO把我坑惨了,原来read和readlines的区别这么大
后端
没事写点啥2 小时前
WeKnora 上下文管理
后端·ai编程