这次源码只做学习参考,来源poi-tl文档,git仓库,建议了解poi-tl的同学再来观看 q(≧▽≦q)
官方学习文档地址:https://deepoove.com/poi-tl/
git源码仓库地址:https://github.com/Sayi/poi-tl
上次介绍了XWPFTemplate和Configure类,上一期在这里
这次我们来介绍一下XWPFDocument
,但在介绍NiceXWPFDocument之前,要先介绍它的父类:XWPFDocument
。
XWPFDocument介绍
XWPFDocument
类位于 Apache POI 库中的 poi-ooxml
模块中,用于操作 Microsoft Word 文档(.docx 格式)。
为什么介绍XWPFDocument,因为TemplateResolve和DefaultRender 出现需要操作org.apache.poi.xwpf.usermodel
的情况,
所以提前打个预防针,先让大家有个大纲在心里。
1. XWPFDocument的主要功能与方法:
主要功能:
- 创建和编辑文档:可以通过
XWPFDocument
创建新的 Word 文档,或者加载已有的文档进行编辑和修改。 - 操作文档内容:可以向文档中添加段落、表格、图片、超链接等内容,并对其进行格式化和样式设置。
- 保存文档:可以将修改后的文档保存到文件系统或输出流中。
主要方法:
- 段落操作:
createParagraph()
: 创建一个新的段落。getParagraphs()
: 获取文档中的所有段落。insertNewParagraph(XmlCursor cursor)
: 在指定位置插入一个新段落。
- 表格操作:
createTable()
: 创建一个新的表格。getTables()
: 获取文档中的所有表格。insertNewTbl(XmlCursor cursor)
: 在指定位置插入一个新表格。
- 图片操作:
addPictureData()
: 向文档中添加图片。getAllPictures()
: 获取文档中的所有图片。
- 超链接操作:
createHyperlink()
: 创建一个超链接。
- 保存操作:
write(OutputStream stream)
: 将文档内容写入输出流。close()
: 关闭文档,释放资源。
总的来说,XWPFDocument
类提供了丰富的方法和功能,用于处理 Word 文档的各种操作,是 Apache POI 中处理 .docx 文档的重要组成部分。
2. XWPFDocument的继承关系
XWPFDocument
类继承自 POIXMLDocument
类,后者是 Apache POI 中处理 Office Open XML 格式文档的基础类。
PS:里面的坑有比较多,比较深,理解就行了(~ ̄▽ ̄)~
Office Open XML介绍,简称:OOXML
Office Open XML(OOXML)是一种开放的文件格式,用于存储办公文档,
如Microsoft Word文档(.docx)、Excel电子表格(.xlsx)、PowerPoint演示文稿(.pptx)等。
它是由Microsoft开发的一种XML(可扩展标记语言)文件格式,旨在取代早期的二进制文件格式,如.doc、.xls、.ppt等。
1. 关于Office Open XML的一些重要特点和优势:
- 开放标准:Office Open XML是一种开放标准,其文件格式规范公开并由Ecma国际组织和国际标准化组织(ISO)标准化。这意味着任何人都可以查看并理解其规范,从而实现对OOXML文档的创建、读取和编辑。
- 基于XML:OOXML文件格式基于XML,这使得文档的内容和结构更易于理解和处理。XML具有良好的可读性和可扩展性,使得对文档进行自动化处理和数据交换变得更加简单。
- 结构清晰:OOXML文档采用了清晰的结构,将文档内容、样式和元数据等信息分开存储,使得文档的组织和管理更加方便。
- 支持现代功能:OOXML格式支持许多现代办公应用程序的高级功能,如图形、嵌入式对象、批注、超链接、标签等,这使得用户可以创建更丰富和复杂的文档。
- 跨平台兼容性:由于OOXML是一种开放标准,因此得到了许多办公应用程序的支持,不仅限于Microsoft Office。许多其他办公套件和文档处理工具都能够创建、读取和编辑OOXML格式的文档。
总的来说,Office Open XML作为一种现代的办公文档格式,具有开放、基于XML、结构清晰、支持现代功能和跨平台兼容性等特点,提供了更灵活、可扩展和可靠的办公文档存储和处理方案。
如果把.docx
的Word文档的文件扩展名改为.zip
或.rar
,会发现整个.docx
是个压缩文件夹。
在文件夹中,包含了许多XML、图像、样式表和其他元数据文件,共同描述和组成了文档的内容、格式和结构。使得.docx
文件成为了一种类似于ZIP文件的包,将各种资源整合在一起,便于存储、传输和处理。压缩结构不仅使得文件占用的空间更小,还有助于提高Word的可靠性和可移植性。
2. 解析.docx
文件结构:探索Word文档的压缩包解压缩后的内容
-
_rels:存储了文档部件之间关系的文件夹。
-
docProps:包含了文档的属性信息,如作者、标题等。
-
word:这是最重要的文件夹,包含了文档的主要内容,其中包括:
-
_rels:存储了文档内部部件之间关系的文件夹。
-
media:媒体文件夹,存储了文档中使用的图片和其他媒体资源。
-
theme:主题文件夹,存储了文档的主题样式信息。
-
fonts:字体文件夹,存储了文档中使用的字体文件。
-
document.xml:包含了文档的主要内容,以XML格式存储。
-
settings.xml:存储了文档的设置信息。
-
styles.xml:存储了文档的样式信息。
-
footnotes.xml:存储了文档的脚注内容。
-
endnotes.xml:存储了文档的尾注内容。
-
headerx.xml / footerx.xml:存储了文档的页眉和页脚内容,其中 x 表示对应的页眉或页脚的编号。
-
numbering.xml:存储了文档中的编号格式信息。
-
-
customXml:存储了自定义XML数据。
-
_rels:存储了关于元数据和文件之间关系的信息。
-
[Content_Types].xml:指定了各个部件的内容类型。
-
thumbnail.jpeg:文档的缩略图。
建议了解即可,没必要深究下去。里面坑很深 o( ̄▽ ̄)ブ
3. Apache POI 的基本概念介绍(需重点理解)
XWPFDocument
类的方法要结合上述OOXML一起看。
XWPFDocument 中的基本概念需要大致理解 Office Open XML (OOXML) 格式的基本结构,因为 .docx 文件实际上是 OOXML 格式的文档。
所以我们实际上是在谈论 Apache POI 库中用于处理 Microsoft Word 文档(.docx)的主要类之一。
这时候我这边要引入在 Apache POI 中两种classes:
1. XWPF前缀的class 与CT前缀的class
- XWPF*的类:
- XWPF 是 XML Word Processing Format 的缩写,表示针对 Word 处理的 XML 格式。
- XWPF 前缀通常用于 Apache POI 中的高级类名,例如 XWPFDocument、XWPFParagraph、XWPFRun 等,这些类用于操作和管理 Word 文档的内容。
- XWPF 类提供了许多方法和属性,用于读取、修改和创建 Word 文档的各种元素,如段落、表格、图片等。
- 位置在poi-ooxml-lite: package org.apache.poi.xwpf.usermodel;
- CT*的类:
- CT 是 Complex Type 的缩写,表示复杂类型,是 Office Open XML 文件格式中定义的一种数据结构。
- CT 前缀通常用于 Apache POI 中表示 OOXML 文件格式中的各种复杂类型,这些类型通常对应着 XML 结构中的元素和属性。
- CT 类型由 XMLBeans 库自动生成,它们是 OOXML 文件格式的抽象表示,用于在 Apache POI 中处理 Word、Excel 和 PowerPoint 等 Office 文档。
- 位置在poi-ooxml-lite: package org.openxmlformats.schemas.wordprocessingml.x2006.main;
2. XWPF与CT 总结
-
XWPF类用于表示 Apache POI 中的高级类,提供了更简单的方法来处理文档,的确更容易理解和使用,因为它提供了一系列方法来直接操作文档的各种元素,例如:XWPFParagraph、XWPFRun等常见的类,但并非所有常见的元素都有相应的XWPF类。有些其他元素可能只能通过CT类来操作。
-
而 CT 类用于表示 OOXML 文件格式中的复杂类型,主要是对 XML 文件中标签的封装,需要用户对 Office Open XML 规范较有深入的了解。它提供了更灵活、更底层的操作方式,但也更复杂,如果需要修改或编写此类代码则需要更加深入的理解。
-
XWPF类在一定程度上包含了对应的CT 类。例如,
XWPFParagraph.getCTP()
方法就可以获取到相应的 CTP 对象,这样用户既可以使用XWPF类提供的方法,也可以直接访问CT 类。而它们一起构成了 Apache POI 库对 Word 文档进行操作和处理的基础。
3. Apache POI 总结
在实际开发动态Word文档过程中:
对于OOXML:
-
单纯代码直接操作OOXML规范的XML结构固然能够实现对Microsoft Office文档的操作,但随着Word文档复杂性的增加,手动编写和维护OOXML格式的XML代码会使开发过程变得复杂且容易出错。
-
另外,OOXML规范中的XML文件在存储时会被压缩,导致所有的XML内容会被压缩在一行里,使得整个文件变得难以阅读和理解。这种情况下,即使是经验丰富的开发人员,在维护文档时候也会在查找和调试代码时遇到很大的困难。所以,现在几乎不会有人直接操作XML文件来动态编辑Word文档。
所以对于OOXML,我的理解是Office Open XML 规范有较为全面和大致的理解即可,不必深究。
对于Apache POI:
- 而Apache POI对OOXML进行了深度封装,将OOXML的复杂结构抽象为CT(Complex Type)类,并进一步封装成XWPF类,然而深度封装也增加代码的复杂度,导致在进行文档处理时需要经历多层封装的过程,增加了代码的抽象程度,有时可能会导致对底层实现细节的不透明性。
- Apache POI的封装大大简化了对文档的操作,旨在简化对Microsoft Office文档的操作,但在实际开发中,仍然需要开发人员对OOXML规范有较为全面的理解。因此,即使使用了Apache POI,开发人员仍然需要花费时间去学习和理解其中的细节,以便更好地利用该库进行文档复杂处理。
所以对于Apache POI,如果在实际开发中需要使用,仍然需要对Apache POI 有大致的理解,至少能大概看懂Apache POI在操作什么,
不然,对于后续业务代码开发及其维护,会逐渐偏离成一个较为严重且无法被被维护的业务代码,俗称:屎山代码。(;´д`)ゞ
对于二次封装框架:
Apache POI由于其底层的复杂性和特殊性,尽管后续框架对Apache POI进行二次封装,如
-
Word:基于Apache POI和JAXB的docx4j,也是接下来继续介绍基于Apache POI的模板引擎的Poi-tl。
-
Execl:基于Apache POI由阿里巴巴开源的EasyExcel,Apache POI自身提供了poi-ooxml-schemas模块等
-
PowerPoint:Apache POI SL,Apache POI XMLSlideShow,emmm……PPT接触的少,有点难找,有兴趣可以自己去找下。
-
当然还有我上述没说到的,欢迎添加
-
上述框架以提高开发效率和降低学习成本,但这并不能完全解决代码难以阅读和理解的问题。在实际应用中,仍然需要投入时间和精力去学习和理解其使用方法,并在项目中逐步积累经验,以提高代码的可读性和维护性,从而更好地理解和调试代码。
针对复杂且多变的业务场景,我个人建议尽量不要把二次封装框架的代码与Apache POI原生代码混合编写,而在混合编写时也要尽量写全注释,
不然,对于后续业务代码开发及其维护,会逐渐偏离成一个较为严重且无法被被维护的业务代码,俗称:屎山代码plus。(;´д`)ゞ
4. 常用标签及其 POI 对象
以下表格是常用的 XML 标签(OOXML)及其对应的 XWPFDocument 和 CT 对象:
XML 标签(OOXML) | XWPFDocument 类 | CT 对象 | 描述 |
---|---|---|---|
<w:document> | XWPFDocument | CTDocument1 | Word 文档的顶级元素 |
<w:p> | XWPFParagraph | CTP | 段落(Paragraph) |
<w:r> | XWPFRun | CTR | 段落中的文本运行(Run) |
<w:br> | XWPFRun | - | 换行符(Break) |
<w:t> | XWPFRun | - | 文本(Text) |
<w:tab> | XWPFRun | - | 制表符(Tab) |
<w:tbl> | XWPFTable | CTTbl | 表格(Table) |
<w:tr> | XWPFTableRow | CTRow | 表格行(Table Row) |
<w:tc> | XWPFTableCell | CTTc | 表格单元格(Table Cell) |
<w:hyperlink> | XWPFHyperlinkRun | CTHyperlink | 超链接(Hyperlink) |
<w:bookmarkStart> | XWPFFieldRun | CTBookmark | 书签起始标记(Bookmark Start) |
<w:bookmarkEnd> | XWPFFieldRun | CTMarkupRange | 书签结束标记(Bookmark End) |
<w:fldSimple> | XWPFFieldRun | CTSimpleField | 简单字段(Simple Field) |
5. XWPFDocument类的树状结构示意图
XWPFDocument
|--- List<XWPFParagraph> paragraphs
| |--- XWPFParagraph
| | |--- List<XWPFRun> runs
| | |--- XWPFRun
| | | |--- Text
| | | |--- Styles and Formatting
|--- List<XWPFTable> tables
| |--- XWPFTable
| |--- List<XWPFTableRow> rows
| |--- XWPFTableRow
| |--- List<XWPFTableCell> cells
| |--- XWPFTableCell
| |--- XWPFParagraph (within cell)
| |--- XWPFRun
| |--- Text
|--- List<XWPFPicture> pictures
| |--- XWPFPicture
|--- List<XWPFHyperlink> hyperlinks
| |--- XWPFHyperlink
|--- List<XWPFFootnote> footnotes
| |--- XWPFFootnote
|--- List<XWPFFootnote> endnotes
| |--- XWPFFootnote
|--- Other properties and methods
6. 终于结束啦ヾ(≧▽≦*)o
这篇主要介绍XWPFDocument,而了解XWPFDocument,必须要先了解Apache POI,
因为只有了解后才能知道为什么NiceXWPFDocument会这样写,以及TemplateResolver为什么会出现XWPFRun的代码。
下一篇继续介绍:
NiceXWPFDocument类:继承自XWPFDocument,对Word文档进行扩展和处理。
后续介绍:
- TemplateResolver类:解析Word文档模板,识别模板中的标签等。
- DefaultRender类:默认的渲染器,根据数据模型填充模板中的标签。
- MetaTemplate类:代表模板中的元素,例如段落、表格等。