这次源码只做学习参考,来源poi-tl文档,git仓库,建议了解poi-tl的同学再来观看 q(≧▽≦q)
官方学习文档地址:https://deepoove.com/poi-tl/
git源码仓库地址:https://github.com/Sayi/poi-tl
poi-tl 源码系列文章:
从零开始看poi-tl源码1 XWPFTemplate和Configure介绍
从零开始看poi-tl源码-2 XWPFDocument介绍
久等了,各位,这次我们来阅读NiceXWPFDocument类,强烈建议看完NiceXWPFDocument的父类 XWPFDocument的介绍,不然可能会看不下去。(╯°□°)╯︵ ┻━┻
0. NiceXWPFDocument 前言
每次查看源码时,先确定起点,也可以叫做锚点,这样可以方便自己在当前代码位置的定位,就像在游戏中使用地图一样。而在 poi-tl 中,最核心的起点,启动 poi-tl 的入口:
XWPFTemplate.compile()
public static XWPFTemplate compile(InputStream inputStream, Configure config) {
try {
XWPFTemplate template = new XWPFTemplate();
template.config = config;
//我们目前到这里
template.doc = new NiceXWPFDocument(inputStream);
template.resolver = new TemplateResolver(template.config);
template.renderer = new DefaultRender();
template.eleTemplates = template.resolver.resolveDocument(template.doc);
return template;
} catch (OLE2NotOfficeXmlFileException e) {
logger.error("Poi-tl currently only supports .docx format");
throw new ResolverException("Compile template failed", e);
} catch (IOException e) {
throw new ResolverException("Compile template failed", e);
}
}
本章重点:
- 结构化文档标记SDT(Structured Document Tag) 点我跳转
1. NiceXWPFDocument 介绍
NiceXWPFDocument 是 Apache POI 中 XWPFDocument 类的一个扩展,旨在提供一些额外的功能和便利性。
- 扩展功能:
NiceXWPFDocument
在XWPFDocument
的基础上进行了扩展,提供了一些额外的功能和特性,使得处理 Word 文档更加便捷和灵活。 - 处理嵌入对象:
NiceXWPFDocument
可以方便地处理文档中的嵌入对象,如图片、图表、嵌入的文档等,提供了相应的方法来添加、读取和处理这些对象。 - 处理结构化文档标记(Structured Document Tags):结构化文档标记是 Word 文档中的一种特殊标记,
NiceXWPFDocument
提供了相关的方法来处理这些标记,如添加、读取、修改等。 - 图表操作:
NiceXWPFDocument
可以处理文档中的图表,包括添加、读取、修改图表等操作,并提供了相关的方法来处理图表数据和样式。 - 编译和合并:
NiceXWPFDocument
支持编译和合并 Word 文档,可以将多个文档合并为一个,也可以将文档编译为指定格式。 - 异常处理:
NiceXWPFDocument
对异常进行了处理和封装,使得在处理 Word 文档时更加稳定和可靠。
总的来说,NiceXWPFDocument 是一个功能强大、灵活性高的扩展类,为处理 Word 文档提供了更多的选择和便利。
NiceXWPFDocument 个成员变量介绍
protected List<XWPFStructuredDocumentTag> structuredDocumentTags = new ArrayList<>();
protected List<XWPFTable> allTables = new ArrayList<XWPFTable>();
protected List<XWPFPicture> allPictures = new ArrayList<XWPFPicture>();
protected List<POIXMLDocumentPart> embedds = new ArrayList<POIXMLDocumentPart>();
protected IdenifierManagerWrapper idenifierManagerWrapper;
protected boolean adjustDoc = false;
protected Map<XWPFChart, PackagePart> chartMappingPart = new HashMap<>();
protected static XWPFRelation DOCUMENT;
XWPFStructuredDocumentTag
XWPFStructuredDocumentTag
是poi-tl封装了Apache POI 中用于表示结构化文档标记(Structured Document Tag,SDT)的类。
结构化文档标记SDT(Structured Document Tag)(重点) :
我个人觉得SDT 是一个比较重要的模块,需要重点关注和理解一下。
SDT是 Microsoft Word 中一种强大的功能,它允许用户在文档中插入和控制结构化数据的展示和输入。SDT 在 Word 文档中作为一种特殊的 XML 元素存在,可以包含文本、表格、图像等内容,并且可以定义数据验证、数据绑定等属性。
以下是 SDT 的一些关键特性和用途:
- 数据模型定义:SDT 允许定义数据模型,即结构化数据的格式和内容。通过定义数据模型,用户可以规范文档中允许的数据类型、数据格式、数据范围等,从而确保文档中的数据符合特定的规范。
- 数据绑定:SDT 可以与外部数据源进行绑定,将文档中的结构化数据与外部数据源(如数据库、XML 文件等)关联起来。这样,在文档中对 SDT 进行操作时,可以直接影响外部数据源,实现数据的同步更新和交互。
- 数据验证:SDT 允许对输入的数据进行验证,确保数据的合法性和完整性。通过定义验证规则和约束条件,可以在文档中预先限制用户输入的内容,从而减少数据错误和不一致性。
- 用户界面控制:SDT 可以定义自定义的用户界面控件,使用户可以通过界面元素(如下拉列表、日期选择器等)方便地输入和编辑结构化数据,提高用户体验和操作效率。
- 文档生成和处理:在程序中,可以通过操作 SDT 实现 Word 文档的自动化生成、数据填充和处理。通过读取和修改 SDT 的内容和属性,可以实现文档模板的动态生成和数据替换,从而简化文档处理流程。
SDT在网上的资料甚少,有额外的方便补充,目前能搜到是Aspose公司的官方文档里有对SDT的集成与封装和例子实现。
这组类在oomxml包中:
包具体地址:package org.openxmlformats.schemas.wordprocessingml.x2006.main;
对应的xml命名空间:"http://schemas.openxmlformats.org/wordprocessingml/2006/main"
注:命名空间(Namespace),这是 XML 元素或属性所属的命名空间的唯一标识符,指示了 Word 文档中所使用的主要命名空间。
在OpenXML中,SDT由一系列复杂类型(Complex Types)组成,它们以CTSdt开头,其中最常见的包括:
类名 | 结构化文档标记 描述 |
---|---|
CTSdtBlock(重点) | 块,通常用于包含大段的结构化内容,例如段落、表格等。 |
CTSdtRun(重点) | 运行,通常用于包含文本或其他简单内容。 |
CTSdtCell(重点) | 单元格,通常用于包含表格单元格中的结构化内容。 |
CTSdtContent | 内容部分,通常包含在SDT中,用于定义和包含结构化内容。 |
CTSdtPr | 属性集合,包含了SDT的各种属性信息,如标签、数据绑定等。 |
CTSdtEndPr | 结尾属性集合,用于定义SDT结束后的属性设置。 |
CTSdtDocPart | 文档部分,用于定义和包含SDT中的文档片段或部分。 |
CTSdtDate | 日期部分,用于定义日期类型的SDT。 |
CTSdtComboBox | 组合框部分,用于定义可选项列表供用户选择的SDT。 |
总的来说,SDT 是 Word 文档中用于管理和操作结构化数据的重要机制。但个人觉得只需要了解即可,非必要时,无需深入。
XWPFStructuredDocumentTag 主要方法:
XWPFStructuredDocumentTag 没有无参构造,只有有参构造,对应着不同级别的结构和内容:
以下是对应方法源码:
// part should be a paragraph(p), but is currently a paragraph's body
public XWPFStructuredDocumentTag(CTSdtRun sdtRun, IBody part) {
this.ctSdtRun = sdtRun;
this.part = part;
this.ctSdtPr = sdtRun.getSdtPr();
this.content = new XWPFStructuredDocumentTagContent(sdtRun.getSdtContent(), part, this);
}
// part should be a document(body), but is currently a paragraph's body
public XWPFStructuredDocumentTag(CTSdtBlock block, IBody part) {
this.ctSdtBlock = block;
this.part = part;
this.ctSdtPr = block.getSdtPr();
this.content = new XWPFStructuredDocumentTagContent(block.getSdtContent(), part, this);
}
// part should be tablerow(tr), but is currently a tablerow'table' body
public XWPFStructuredDocumentTag(CTSdtCell sdtCell, XWPFTableRow xwpfTableRow, IBody part) {
this.ctSdtCell = sdtCell;
this.part = part;
this.ctSdtPr = sdtCell.getSdtPr();
this.content = new XWPFStructuredDocumentTagContent(sdtCell.getSdtContent(), xwpfTableRow, part, this);
}
- ctSdtRun:
- 代表一个运行级别的 SDT,通常用于包含在段落(
XWPFParagraph
)中,可以包含文本和其他行内元素。 - 在 Word 文档中,运行级别的 SDT 可以嵌套在段落内的任何位置,因此可以包含在段落的文本之间,或者作为段落的一部分出现。
- 代表一个运行级别的 SDT,通常用于包含在段落(
- ctSdtBlock:
- 代表一个块级别的 SDT,通常用于包含在段落、表格单元格(
XWPFTableCell
)或者表格行(XWPFTableRow
)中,可以包含更复杂的内容,如多个段落、表格、图片等。 - 在 Word 文档中,块级别的 SDT 通常用于包含更复杂的结构,例如整个段落、表格或者其他大块的内容。
- 代表一个块级别的 SDT,通常用于包含在段落、表格单元格(
- ctSdtCell:
- 代表一个单元格级别的 SDT,用于包含在表格单元格(
XWPFTableCell
)中,可以包含表格、文本等内容。 - 在 Word 文档中,单元格级别的 SDT 用于在表格中的特定单元格内部定义结构化内容。
- 代表一个单元格级别的 SDT,用于包含在表格单元格(
因此,它们的区别主要在于所处的层级和所能包含的内容的复杂程度。ctSdtRun
适用于简单的内联文本或者行内元素,ctSdtBlock
适用于更复杂的、大块的内容,而 ctSdtCell
适用于包含在表格单元格中的内容。
IBody的作用:
IBody
接口的作用是表示该标记所在的文档主体部分。而在构造 XWPFStructuredDocumentTag
对象时,通过传入 IBody
接口的实例来指定该标记所在的位置。个人猜想,通过IBody
接口的实例,XWPFStructuredDocumentTag
可以知道自己在文档中的位置,并且可以通过该接口实例来操作所在位置的文档内容.
XWPFStructuredDocumentTagContent 介绍
通过看到XWPFStructuredDocumentTag
方法,我们知道了底层还有一个叫XWPFStructuredDocumentTagContent
的类,我们浅浅看看。再往下看真就没完没了啦,顶不住啦(╯°□°)╯︵ ┻━┻
XWPFStructuredDocumentTagContent 主要功能和作用包括:
- 解析SDT内容:根据传入的SDT内容块(CTSdtContentRun、CTSdtContentBlock、CTSdtContentCell),将其中包含的文本、段落、表格、运行等内容解析并存储起来。
- 添加、删除、更新SDT内容中的文本、段落、表格等元素。
- 获取SDT内容中的各种元素列表,如段落列表、表格列表、运行列表等。
- 提供文本内容获取方法,可以获取SDT中的所有文本内容。
- 支持在SDT内容中插入新的文本、段落、表格等元素。
- 支持对SDT内容中的元素进行操作,如插入、删除、更新运行元素(XWPFRun)等。
XWPFStructuredDocumentTagContent 总结:
这个类用于管理和操作结构化文档标记中的内容部分,主要来处理SDT中的各种内容元素。
接下来继续看NiceXWPFDocument
其他成员变量
XWPFTable,XWPFPicture
这两个类都是在org.apache.poi.xwpf.usermodel
包。
protected List<XWPFTable> allTables = new ArrayList<XWPFTable>();
protected List<XWPFPicture> allPictures = new ArrayList<XWPFPicture>();
allTables
:存储了文档中的所有表格(XWPFTable
对象)。表格是文档中一种常见的结构,用于以行和列的形式组织和显示数据。
allPictures
:存储了文档中的所有图片(XWPFPicture
对象)。这些图片可以是文档中插入的图像文件,比如JPG、PNG等格式的图片。
而刚才介绍的structuredDocumentTags
存储了文档中的所有结构化文档标记(Structured Document Tag,SDT)。结构化文档标记是一种特殊的文档元素,用于将文档的内容分成逻辑部分并提供结构化的信息,比如日期、下拉框等,文本内容只是其中一种。
通过将这些对象存储在列表中,可以方便地对它们进行管理和操作,比如遍历、搜索、删除等。
POIXMLDocumentPart,IdenifierManagerWrapper,adjustDoc
protected List<POIXMLDocumentPart> embedds = new ArrayList<POIXMLDocumentPart>();
protected IdenifierManagerWrapper idenifierManagerWrapper;
protected boolean adjustDoc = false;
embedds
: 这个列表存储了文档中嵌入的其他文档部分(POIXMLDocumentPart
对象)。在一些情况下,文档可以包含其他文档的一部分.这个列表用于跟踪这些嵌入的部分。包含在文档中的不同部分,例如嵌入的对象、链接到的外部文件等。在这个列表中,每个 POIXMLDocumentPart
对象代表一个附件的部分,并提供了访问和操作该附件数据的方法。通过遍历这个列表,可以获取文档中的所有附件,并进行相关操作,比如把两份.docx文档进行合并。
在方法NiceXWPFDocument.readRun(XWPFRun run)
中有使用到idenifierManagerWrapper
和adjustDoc
:
idenifierManagerWrapper
:
idenifierManagerWrapper
是一个标识符管理器的包装器,用于管理文档中各个元素的标识符(ID)。- 在读取文档的过程中,通过
idenifierManagerWrapper.reserve(id)
方法保证了文档中的标识符的唯一性,避免了标识符的重复。
adjustDoc
:
adjustDoc
是一个布尔值,用于控制是否需要调整文档。- 当
adjustDoc
为true
时,表示需要对文档进行调整;当为false
时,则不需要。 - 在代码中,当需要调整文档时,会根据
adjustDoc
的值,判断是否需要更新文档中的部分内容,以保证标识符的唯一性。
XWPFChart,PackagePart
这XWPFChart
是在org.apache.poi.xwpf.usermodel
包。
protected Map<XWPFChart, PackagePart> chartMappingPart = new HashMap<>();
用于存储 XWPFChart
对象与其对应的 PackagePart
对象之间的映射关系。在处理 Word 文档中的图表时,XWPFChart
表示文档中的图表对象,而 PackagePart
表示图表在 OOXML 文件中的部分。
具体来说,XWPFChart
表示 Word 文档中的图表,它包含了图表的数据、样式和布局等信息。而 PackagePart
则表示 OOXML 文件中存储图表信息的部分,它可以是 Word 文档的一部分,也可以是其他 Office 文档格式(如 Excel 或 PowerPoint)中的一部分。
通过在 chartMappingPart
中存储 XWPFChart
和 PackagePart
对象之间的映射关系,可以方便地在处理 Word 文档时,根据图表对象找到对应的部分,或者根据部分找到对应的图表对象,从而实现对图表内容的读取、修改和处理等操作。
XWPFRelation
protected static XWPFRelation DOCUMENT;
在 Apache POI 中,XWPFRelation 是一种表示 Word 文档中不同部分之间关系的对象。它主要用于描述 Word 文档中各个部分(如段落、表格、图像等)之间的关联关系。每个 XWPFRelation 对象都代表了一种特定类型的关系,例如主文档与嵌入的对象之间的关系、主文档与附加文档之间的关系等。这些关系在 Word 文档的内部结构中起着重要的作用,可以帮助 Apache POI 在读取、创建和编辑 Word 文档时维护正确的结构。
XWPFRelation 对象通常用于以下几个方面:
- 创建新的 Word 文档元素:在创建 Word 文档时,可以使用 XWPFRelation 对象来创建新的段落、表格、图像等元素,并将它们与文档进行关联。
- 读取和解析 Word 文档:在读取 Word 文档时,XWPFRelation 对象用于识别和解析文档中的不同部分,并确定它们之间的关系,以便正确地还原文档的结构。
- 编辑和修改 Word 文档:在编辑或修改 Word 文档时,XWPFRelation 对象可以帮助确定要添加、删除或修改的部分,并确保修改后的文档仍然保持正确的结构。
总的来说,XWPFRelation 是 Apache POI 中用于管理 Word 文档内部结构的重要工具,它有助于开发人员有效地操作和处理 Word 文档的内容。
本章总结:
NiceXWPFDocument 成员变量总结
- structuredDocumentTags:类型为
List<XWPFStructuredDocumentTag>
,用于存储文档中的结构化文档标记(SDT)对象。 - allTables:类型为
List<XWPFTable>
,用于存储文档中的所有表格对象。 - allPictures:类型为
List<XWPFPicture>
,用于存储文档中的所有图片对象。 - embedds:类型为
List<POIXMLDocumentPart>
,用于存储文档中的嵌入对象。 - idenifierManagerWrapper:类型为
IdenifierManagerWrapper
,可能是用于管理文档中元素的唯一标识符的包装器。 - adjustDoc:类型为
boolean
,可能用于指示是否调整文档。 - chartMappingPart:类型为
Map<XWPFChart, PackagePart>
,用于存储文档中图表对象及其对应的包装部分。 - DOCUMENT:类型为
XWPFRelation
,可能是表示文档的关系类型。
这些成员变量用于在 NiceXWPFDocument 类中存储文档的结构化数据和相关信息,以便进行读取、修改和操作文档内容。
下篇是关于NiceXWPFDocument 的方法介绍,敬请期待。o( ̄▽ ̄)ブ