>>> from env_helper import info; info()
页面更新时间: 2024-04-04 19:45:56
运行环境:
    Linux发行版本: Debian GNU/Linux 12 (bookworm)
    操作系统内核: Linux-6.1.0-18-amd64-x86_64-with-glibc2.36
    Python版本: 3.11.2

2.6. 实例:为章节添加编号

章节编号可以清晰的了解文档结构。Word 软件可以使用自动编号的功能,但是使用起来需要专门学习一下,而且经常会出现问题,如果对 Word 软件,以及标题、样式等概念不是很熟悉,遇到问题有时也很难解决。所以,大部分用户实际使用的时候都是手工编号,而手工编号的问题在于修改,尤其是前面章节调整时,会导致需要重新编号,非常地繁琐。

2.6.1. 场景说明

这个实例说明使用 Python 给 DOCX 中章节添加编号的功能,要求在 DOCX 中将章节正确地设置好标题的级别。这个是最基本的要求,不然程序也无法判断哪些是标题。

这里只演示到三级标题,四级标题或者五级六级他们的原理都是相同的。

2.6.2. 解决思路

读取出章节样式,将章的标题使用数字, 二级标题与三级标题则要在前面添加上一级的编号 。

2.6.3. 解决办法

获取到标题,将对应的编号插入标题前。 先打开文档:

>>> from docx import Document
>>> document = Document('style2.docx')

为了添加序号,我们需要先看一下要对哪些命名样式进行添加:

>>> for p in document.paragraphs:
>>>     name= p.style.name
>>>     print(name, )
Normal
Heading 1
Heading 2
Heading 2
Heading 1
Heading 2
Heading 3
Heading 1
Heading 2
Heading 2
Heading 3
Heading 3

根据样式获取标题,这里都是默认的样式名称。

>>> head1=0
>>> head2=0
>>> head3=0
>>>
>>> for para in document.paragraphs:
>>>     style_name= para.style.name
>>>     if style_name=="Heading 1":
>>>         head1+=1
>>>         for i in range(len(para.runs)):
>>>             para.runs[i].text = para.runs[i].text.replace(
>>>                 para.text, str(head1)+" "+para.text
>>>             )
>>>         head2=0
>>>         head3=0
>>>     if style_name=="Heading 2":
>>>         head2+=1
>>>         for i in range(len(para.runs)):
>>>             para.runs[i].text = para.runs[i].text.replace(
>>>                 para.text, str(head1)+"."+str(head2)+" "+para.text
>>>             )
>>>     if style_name=="Heading 3":
>>>         head3+=1
>>>         for i in range(len(para.runs)):
>>>             para.runs[i].text = para.runs[i].text.replace(
>>>                 para.text,
>>>                 str(head1)+"."+str(head2)+"."+str(head3)+" "+para.text
>>>             )

将文件另存为一个新文件。

>>> document.save('xx_numbered.docx')

2.6.4. 总结

输出标题内容看一下结果 :

>>> document1 = Document('xx_numbered.docx')
>>> for para1 in document1.paragraphs[:6]:
>>>     name= para1.style.name
>>>     if name.startswith('Heading'):
>>>         print(' ' * int(name.split()[-1]) * 2,  para1.text, '(', name, ')')
1 First ( Heading 1 )
  1.1 Eg1 ( Heading 2 )
  1.2 Eg2 ( Heading 2 )
2 Aaasd ( Heading 1 )
  2.1 Eg3 ( Heading 2 )

使用这种方法可以简化我们去手动添加的时间,优化可读性。

对于已经添加了序号的文档,在修改过程中会面临重新编号的问题。 对于这个问题,可以用字符串处理的技术,如正则表达式得到标题的文字, 从而在重新编号过程中忽略掉原来的编号。

还有一个问题,如果要进行重新编号,则需要将原来的编号去掉。 去掉编号的过程就是字符串处理的功能,可以使用正则表达式模块。