Bootstrap

从零开始看poi-tl源码3 NiceXWPFDocument 成员变量介绍(上)

这次源码只做学习参考,来源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 类的一个扩展,旨在提供一些额外的功能和便利性。

  1. 扩展功能NiceXWPFDocumentXWPFDocument 的基础上进行了扩展,提供了一些额外的功能和特性,使得处理 Word 文档更加便捷和灵活。
  2. 处理嵌入对象NiceXWPFDocument可以方便地处理文档中的嵌入对象,如图片、图表、嵌入的文档等,提供了相应的方法来添加、读取和处理这些对象。
  3. 处理结构化文档标记(Structured Document Tags):结构化文档标记是 Word 文档中的一种特殊标记,NiceXWPFDocument提供了相关的方法来处理这些标记,如添加、读取、修改等。
  4. 图表操作NiceXWPFDocument可以处理文档中的图表,包括添加、读取、修改图表等操作,并提供了相关的方法来处理图表数据和样式。
  5. 编译和合并NiceXWPFDocument支持编译和合并 Word 文档,可以将多个文档合并为一个,也可以将文档编译为指定格式。
  6. 异常处理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 的一些关键特性和用途

  1. 数据模型定义:SDT 允许定义数据模型,即结构化数据的格式和内容。通过定义数据模型,用户可以规范文档中允许的数据类型、数据格式、数据范围等,从而确保文档中的数据符合特定的规范。
  2. 数据绑定:SDT 可以与外部数据源进行绑定,将文档中的结构化数据与外部数据源(如数据库、XML 文件等)关联起来。这样,在文档中对 SDT 进行操作时,可以直接影响外部数据源,实现数据的同步更新和交互。
  3. 数据验证:SDT 允许对输入的数据进行验证,确保数据的合法性和完整性。通过定义验证规则和约束条件,可以在文档中预先限制用户输入的内容,从而减少数据错误和不一致性。
  4. 用户界面控制:SDT 可以定义自定义的用户界面控件,使用户可以通过界面元素(如下拉列表、日期选择器等)方便地输入和编辑结构化数据,提高用户体验和操作效率。
  5. 文档生成和处理:在程序中,可以通过操作 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);
}
  1. ctSdtRun
    • 代表一个运行级别的 SDT,通常用于包含在段落(XWPFParagraph)中,可以包含文本和其他行内元素。
    • 在 Word 文档中,运行级别的 SDT 可以嵌套在段落内的任何位置,因此可以包含在段落的文本之间,或者作为段落的一部分出现。
  2. ctSdtBlock
    • 代表一个块级别的 SDT,通常用于包含在段落、表格单元格(XWPFTableCell)或者表格行(XWPFTableRow)中,可以包含更复杂的内容,如多个段落、表格、图片等。
    • 在 Word 文档中,块级别的 SDT 通常用于包含更复杂的结构,例如整个段落、表格或者其他大块的内容。
  3. ctSdtCell
    • 代表一个单元格级别的 SDT,用于包含在表格单元格(XWPFTableCell)中,可以包含表格、文本等内容。
    • 在 Word 文档中,单元格级别的 SDT 用于在表格中的特定单元格内部定义结构化内容。

因此,它们的区别主要在于所处的层级和所能包含的内容的复杂程度。ctSdtRun 适用于简单的内联文本或者行内元素,ctSdtBlock 适用于更复杂的、大块的内容,而 ctSdtCell 适用于包含在表格单元格中的内容。

IBody的作用:

IBody 接口的作用是表示该标记所在的文档主体部分。而在构造 XWPFStructuredDocumentTag 对象时,通过传入 IBody 接口的实例来指定该标记所在的位置。个人猜想,通过IBody 接口的实例,XWPFStructuredDocumentTag 可以知道自己在文档中的位置,并且可以通过该接口实例来操作所在位置的文档内容.

XWPFStructuredDocumentTagContent 介绍

通过看到XWPFStructuredDocumentTag 方法,我们知道了底层还有一个叫XWPFStructuredDocumentTagContent的类,我们浅浅看看。再往下看真就没完没了啦,顶不住啦(╯°□°)╯︵ ┻━┻

XWPFStructuredDocumentTagContent 主要功能和作用包括:
  1. 解析SDT内容:根据传入的SDT内容块(CTSdtContentRun、CTSdtContentBlock、CTSdtContentCell),将其中包含的文本、段落、表格、运行等内容解析并存储起来。
  2. 添加、删除、更新SDT内容中的文本、段落、表格等元素。
  3. 获取SDT内容中的各种元素列表,如段落列表、表格列表、运行列表等。
  4. 提供文本内容获取方法,可以获取SDT中的所有文本内容。
  5. 支持在SDT内容中插入新的文本、段落、表格等元素。
  6. 支持对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)中有使用到idenifierManagerWrapperadjustDoc

idenifierManagerWrapper

  • idenifierManagerWrapper 是一个标识符管理器的包装器,用于管理文档中各个元素的标识符(ID)
  • 在读取文档的过程中,通过 idenifierManagerWrapper.reserve(id) 方法保证了文档中的标识符的唯一性,避免了标识符的重复

adjustDoc

  • adjustDoc 是一个布尔值,用于控制是否需要调整文档
  • adjustDoctrue 时,表示需要对文档进行调整;当为 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 中存储 XWPFChartPackagePart 对象之间的映射关系,可以方便地在处理 Word 文档时,根据图表对象找到对应的部分,或者根据部分找到对应的图表对象,从而实现对图表内容的读取、修改和处理等操作。

XWPFRelation

    protected static XWPFRelation DOCUMENT;

在 Apache POI 中,XWPFRelation 是一种表示 Word 文档中不同部分之间关系的对象。它主要用于描述 Word 文档中各个部分(如段落、表格、图像等)之间的关联关系。每个 XWPFRelation 对象都代表了一种特定类型的关系,例如主文档与嵌入的对象之间的关系、主文档与附加文档之间的关系等。这些关系在 Word 文档的内部结构中起着重要的作用,可以帮助 Apache POI 在读取、创建和编辑 Word 文档时维护正确的结构。

XWPFRelation 对象通常用于以下几个方面:

  1. 创建新的 Word 文档元素:在创建 Word 文档时,可以使用 XWPFRelation 对象来创建新的段落、表格、图像等元素,并将它们与文档进行关联。
  2. 读取和解析 Word 文档:在读取 Word 文档时,XWPFRelation 对象用于识别和解析文档中的不同部分,并确定它们之间的关系,以便正确地还原文档的结构。
  3. 编辑和修改 Word 文档:在编辑或修改 Word 文档时,XWPFRelation 对象可以帮助确定要添加、删除或修改的部分,并确保修改后的文档仍然保持正确的结构。

总的来说,XWPFRelation 是 Apache POI 中用于管理 Word 文档内部结构的重要工具,它有助于开发人员有效地操作和处理 Word 文档的内容。

本章总结:

NiceXWPFDocument 成员变量总结

  1. structuredDocumentTags:类型为 List<XWPFStructuredDocumentTag>,用于存储文档中的结构化文档标记(SDT)对象。
  2. allTables:类型为 List<XWPFTable>,用于存储文档中的所有表格对象。
  3. allPictures:类型为 List<XWPFPicture>,用于存储文档中的所有图片对象。
  4. embedds:类型为 List<POIXMLDocumentPart>,用于存储文档中的嵌入对象。
  5. idenifierManagerWrapper:类型为 IdenifierManagerWrapper,可能是用于管理文档中元素的唯一标识符的包装器。
  6. adjustDoc:类型为 boolean,可能用于指示是否调整文档。
  7. chartMappingPart:类型为 Map<XWPFChart, PackagePart>,用于存储文档中图表对象及其对应的包装部分。
  8. DOCUMENT:类型为 XWPFRelation,可能是表示文档的关系类型。

这些成员变量用于在 NiceXWPFDocument 类中存储文档的结构化数据和相关信息,以便进行读取、修改和操作文档内容

下篇是关于NiceXWPFDocument 的方法介绍,敬请期待。o( ̄▽ ̄)ブ

;