Docx文档如何实现的自动编号?
小明 Lv6

📃 不得不佩服优秀软件的规范

上次讲到使用Freemarker生成word文档,这种方案对不常变更的需求是非常不错的。但是,哪有产品需求不变更的?
今天就遇到了一个坑,标题的编号问题。
虽然我们可以动态替换文本,但是要是想借用docx自己的文档规范生成,岂不是一劳永逸?

序号定义

像往常一样,我们把一个docx文档解压,可以得到目录结构,而序号的定义就存在numbering.xml中,包括从几开始、序号的样式:
image

有两种类型,abstractNumnum,其中每个numId对应一个abstractNumId,每个abstractNumId对应一组格式,举例如下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
<!-- abstractNum -->
<!-- 对应一组格式 -->
<w:abstractNum w:abstractNumId="12">
<w:nsid w:val="7A70A8F6"/>
<w:multiLevelType w:val="singleLevel"/>
<w:tmpl w:val="7A70A8F6"/>
<!-- 对应这一组格式中的一种格式 -->
<w:lvl w:ilvl="0" w:tentative="0">
<!-- 表示这种格式从几开始 -->
<w:start w:val="1"/>
<!-- 表示这种格式是什么类型的 -->
<w:numFmt w:val="chineseCounting"/>
<w:suff w:val="nothing"/>
<!-- 表示这种格式的样式 -->
<w:lvlText w:val="(%1)"/>
<w:lvlJc w:val="left"/>
<w:rPr>
<w:rFonts w:hint="eastAsia"/>
</w:rPr>
</w:lvl>
</w:abstractNum>

<!-- num -->
<w:num w:numId="1">
<w:abstractNumId w:val="12"/>
</w:num>

序号使用

主文档document.xml引用序号格式如下:

1
2
3
4
5
6
<w:numPr>
<!-- 用来确定是同个abstractNumId的不同格式 -->
<w:ilvl w:val="0"/>
<!-- 其中 `numId`就是引用`numbering.xml`中的定义 -->
<w:numId w:val="1"/>
</w:numPr>

每个numId对应一个abstractNumId,自动编号用两次就会自上而下生成“一、…… 二、……”。此时,这两段标题的numId是一样的。不需要自动编号的段落的numId为0,且没有对应的abstractNumId。

总结

带编号的段落在document.xml生成一个numId和ilvl,每个numId对应一个abstractNumId,每个abstractNumId有一组格式序列,每个ilvl对应改组格式序列的一种格式。每个格式有start确定起始编号,numFmt确定格式类型,lvlText确定格式样式。通过numFmt和lvlText的组合确定自动编号的最终的样式

关注获取更多资源

image
 评论