POI in Action

文章介绍了ApachePOI组件的依赖,包括对OLE2和OOXML文件格式的支持,以及不同API的使用场景,如SAXAPI和SXSSFWorkbook对大数据处理的优化。此外,提到了EasyExcel的读写操作和注解配置,以及从POI4.0.0版本开始的JDK要求。最后,讨论了POI的安全升级,特别是5.2.3版本修复的XXE漏洞,并提及了EasyExcel接口的变动。
摘要由CSDN通过智能技术生成

1 POI 组件依赖

按需引入对应依赖 (给出官方的指引)

组件作用Maven依赖
POIFSOLE2 Filesystempoi
HPSFOLE2 Property Setspoi
HSSFExcel XLSpoi
HSLFPowerPoint PPTpoi-scratchpad
HWPFWord DOCpoi-scratchpad
HDGFVisio VSDpoi-scratchpad
HPBFPublisher PUBpoi-scratchpad
HSMFOutlook MSGpoi-scratchpad
DDFEscher common drawingspoi
HWMFWMF drawingspoi-scratchpad
OpenXML4JOOXMLpoi-ooxml plus either poi-ooxml-schemas or ooxml-schemas and ooxml-security
XSSFExcel XLSXpoi-ooxml
XSLFPowerPoint PPTXpoi-ooxml
XWPFWord DOCXpoi-ooxml
XDGFVisio VSDXpoi-ooxml
Common SLPowerPoint PPT 和 PPTX 共用组件poi-scratchpad and poi-ooxml
Common SSExcel XLS 和 XLSX 共用组件poi-ooxml
XSSFExcel XLSXpoi-ooxml
XSLFPowerPoint PPTXpoi-ooxml
XWPFWord DOCXpoi-ooxml
XDGFVisio VSDXpoi-ooxml
Common SLPowerPoint PPT 和 PPTX 共用组件poi-scratchpad and poi-ooxml
Common SSExcel XLS 和 XLSX 共用组件poi-ooxml

2 什么是 OLE2 和 OOXML

OLE2 和 OOXML 本质上都是一种文件格式规范或标准,平时看到的 excel 中,有字体、公式、颜色、图片等等,看起来非常复杂,但是在文件结构上都遵循着固定的格式。

OLE2 文件一般包括 xls、doc、ppt 等,是二进制格式的文件。 相关内容可以参考: 复合文档Ole对象二进制储存格式 。

OOXML文件一般包括 xlsx、docx、pptx 等。该类文件以指定格式的 xml 为基础并以 zip 格式压缩,这里我利用解压工具解压本地的一个 xlsx 文件,可以看到以下文件结构,在本文例子中,我们会重点关注 sharedStrings.xml 和 sheet1.xml 的内容,因为使用 SAX API 时必须用到:

在这里插入图片描述

包名描述
org.apache.poi.ssExcel API,底层解析方式类似 DOM,效率较低,内存占用较大
org.apache.poi.hssfExcel XLS API,采用 SAX API 方式读写
org.apache.poi.xssfExcel XLSX API,采用 SAX API 方式读写

POI SAX 方式的 API 非常繁琐,使用时须熟练掌握 OLE2 或 OOXML 的规范

SXSSFWorkbook

SXSSFWorkbook 专门处理大数据,对于大型 Excel 的创建且不会内存溢出,主要原理是借助临时存储空间生成 Excel.

SXSSFWorkbook 是 Streaming 版本的 XSSFWorkbook, 它只会保存最新的 Excel rows 在内存里供查看, 在此之前的 Excel rows 都会被写入到硬盘里 (e.g. Windows 写入到 C盘 根目录下的 temp 文件夹). 被写入到硬盘里的 rows是 不可见 / 不可访问的. 只有还在内存的才可被访问到

注: HSSFWorkbookXSSFWorkbook 的 Excel Sheet 导出条数上限是 [65535行, 256 列] (<=2003版) , 或 [1048576行, 16384列] (>=2007版) , 如果数据量超过了此上限, 那么可以使用 SXSSFWorkbook 来导出. (实际中上万条数据, 甚至上千条数据就可以考虑使用 SXSSFWorkbook了)

poi 4.0.0 版本需要 JDK 1.8 以上,如果是 JDK 1.7 就使用 3.9 版本

// 这样表示 SXSSFWorkbook 只会保留 100条 数据在内存中, 其它的数据都会写到磁盘里, 这样的话占用的内存就会很少
sxssfWorkbook = new SXSSFWorkbook(fechXSSFWorkbook(filePath), 100);
SXSSFSheet sheet = sxssfWorkbook.getSheetAt(0); // 获取第一个 Sheet 页
for (int i = 0; i < 50; i++) {
    for (int z = 0; z < 10000; z++) {
	SXSSFRow row = sheet.createRow(i*10000+z);
	    for (int j = 0; j < 10; j++) {
		    row.createCell(j).setCellValue("你好:"+j);
		}
	}
}
outputStream = new BufferedOutputStream(new FileOutputStream(filePath));
sxssfWorkbook.write(outputStream);
outputStream.flush();
sxssfWorkbook.dispose(); // 释放 workbook 所占用的所有资源

3 EasyExcel

3.1 关于常见类解析

  • EasyExcel 入口类,用于构建开始各种操作
  • ExcelReaderBuilder ExcelWriterBuilder 构建出一个 ReadWorkbook WriteWorkbook,可以理解成一个Excel 对象,一个 Excel 只需构建一个
  • ExcelReaderSheetBuilder ExcelWriterSheetBuilder 构建出一个 ReadSheet WriteSheet 对象,可以理解成 Excel 里面的一页,每一页都要构建一个
  • ReadListener 在每一行读取完毕后都会调用 ReadListener 来处理数据
  • WriteHandler 在每一个操作包括创建单元格、创建表格等都会调用 WriteHandler 来处理数据
  • 所有配置都是继承的,Workbook 的配置会被 Sheet 继承,所以在用 EasyExcel 设置参数的时候,在 EasyExcel...sheet() 方法之前作用域是整个 Sheet, 之后针对单个 Sheet

3.2 读

3.2.1 注解

  • ExcelProperty 指定当前字段对应 Excel 中的那一列。可以根据名字或者 index 去匹配。当然也可以不写,默认第一个字段就是 index=0,以此类推。千万注意,要么全部不写,要么全部用 index,要么全部用名字去匹配。千万别三个混着用,除非你非常了解源代码中三个混着用怎么去排序的。
  • ExcelIgnore 默认所有字段都会和 Excel 去匹配,加了这个注解会忽略该字段
  • DateTimeFormat 日期转换,用 String 去接收 Excel 日期格式的数据会调用这个注解。里面的 value参照java.text.SimpleDateFormat
  • NumberFormat 数字转换,用String去接收 Excel 数字格式的数据会调用这个注解。里面的 value 参照 java.text.DecimalFormat
  • ExcelIgnoreUnannotated 默认不加 ExcelProperty 的注解的都会参与读写,加了不会参与

3.2.2 参数

3.2.2.1 通用参数

ReadWorkbook, ReadSheet 都会有的参数,如果为空,默认使用上级。

  • converter 转换器,默认加载了很多转换器。也可以自定义。
  • readListener 监听器,在读取数据的过程中会不断的调用监听器。
  • headRowNumber 需要读的表格有几行头数据。默认有一行头,也就是认为第二行开始起为数据。
  • headclazz 二选一。读取文件头对应的列表,会根据列表匹配数据,建议使用class。
  • clazzhead 二选一。读取文件的头对应的class,也可以使用注解。如果两个都不指定,则会读取全部数据。
  • autoTrim 字符串、表头等数据自动 trim
  • password 读的时候是否需要使用密码
3.2.2.2 ReadWorkbook(理解成Excel对象)参数
  • excelType 当前excel的类型 默认会自动判断
  • inputStreamfile二选一。读取文件的流,如果接收到的是流就只用,不用流建议使用file参数。因为使用了inputStream EasyExcel会帮忙创建临时文件,最终还是file
  • fileinputStream二选一。读取文件的文件。
  • autoCloseStream 自动关闭流。
  • readCache 默认小于5M用 内存,超过5M会使用 EhCache,这里不建议使用这个参数。
3.2.2.3 ReadSheet(就是Excel的一个Sheet)参数
  • sheetNo 需要读取Sheet的编码,建议使用这个来指定读取哪个Sheet
  • sheetName 根据名字去匹配 Sheet, Excel 2003不支持根据名字去匹配

3.3 写

3.3.1 注解

  • ExcelProperty index 指定写到第几列,默认根据成员变量排序。value指定写入的名称,默认成员变量的名字,多个value可以参照快速开始中的复杂头
  • ExcelIgnore 默认所有字段都会写入 Excel,这个注解会忽略这个字段
  • DateTimeFormat 日期转换,将Date写到 Excel 会调用这个注解。里面的 value 参照java.text.SimpleDateFormat
  • NumberFormat 数字转换,用Number写 Excel 会调用这个注解。里面的 value 参照java.text.DecimalFormat
  • ExcelIgnoreUnannotated 默认不加ExcelProperty 的注解的都会参与读写,加了不会参与

3.3.2 参数

3.3.2.1 通用参数

WriteWorkbook, WriteSheet, WriteTable 都会有的参数,如果为空,默认使用上级.

  • converter 转换器,默认加载了很多转换器。也可以自定义.
  • writeHandler 写的处理器。可以实现WorkbookWriteHandler, SheetWriteHandler, RowWriteHandler, CellWriteHandler, 在写入 Excel 的不同阶段会调用
  • relativeHeadRowIndex 距离多少行后开始。也就是开头空几行
  • needHead 是否导出头
  • headclazz 二选一。写入文件的头列表,建议使用 class
  • clazzhead 二选一。写入文件的头对应的 class,也可以使用注解
  • autoTrim 字符串、表头等数据自动 trim
3.3.2.2 WriteWorkbook(理解成 Excel 对象)参数
  • excelType 当前excel的类型 默认 xlsx
  • outputStreamfile 二选一。写入文件的流
  • fileoutputStream 二选一。写入的文件
  • templateInputStream 模板的文件流
  • templateFile 模板文件
  • autoCloseStream 自动关闭流。
  • password 写的时候是否需要使用密码
  • useDefaultStyle 写的时候是否是使用默认头
3.3.2.3 WriteSheet(就是 Excel 的一个 Sheet)参数
  • sheetNo 需要写入的编码。默认0
  • sheetName 需要些的 Sheet 名称, 默认同 sheetNo
3.3.2.4 WriteTable(就把 Excel 的一个 Sheet, 一块区域看一个 table)参数
  • tableNo 需要写入的编码. 默认 0

POI upgrade to 5.2.3

Apache POI 版本 <= 4.1.0 中, 使用 XSSFExportToXml 转换 Excel 文档时,
可在 xmlMaps.xml 加入恶意代码制作成 excel 文档, 代码解析恶意文档时,
可以允许攻击者通过 XML External Entity (XXE) 处理在服务器读取文件资源或发送外部请求.
漏洞是在使用 XSSFExportToXml 类 xlsx 转 xml 时触发.

poi > 5.2.3
poi_ooxml > 5.2.3
去掉 poi_ooxml_schemas 依赖

EasyExcel upgrading poi to 5.2.3

接口变动栗子
org.apache.poi.ss.usermodel.CellBaseremoveremove method CellType getCachedFormulaResultTypeEnum()
org.apache.poi.ss.usermodel.CellStyleremove|change|addreturn short change to int
org.apache.poi.ss.usermodel.Sheetadd
org.apache.poi.ss.usermodel.Workbookremove|change|addshort to int
add method #createEvaluationWorkbook
add attribute cellReferenceType
注:下文中的 *** 代表文件名中的版本号。 # 【poi-ooxml-***.jar中文文档.zip】 中包含: 中文文档:【poi-ooxml-***-javadoc-API文档-中文(简体)版.zip】 jar包下载地址:【poi-ooxml-***.jar下载地址(官方地址+国内镜像地址).txt】 Maven依赖:【poi-ooxml-***.jar Maven依赖信息(可用于项目pom.xml).txt】 Gradle依赖:【poi-ooxml-***.jar Gradle依赖信息(可用于项目build.gradle).txt】 源代码下载地址:【poi-ooxml-***-sources.jar下载地址(官方地址+国内镜像地址).txt】 # 本文件关键字: poi-ooxml-***.jar中文文档.zip,java,poi-ooxml-***.jar,org.apache.poi,poi-ooxml,***,org.apache.poi.ooxml,jar包,Maven,第三方jar包,组件,开源组件,第三方组件,Gradle,apache,poi,ooxml,中文API文档,手册,开发手册,使用手册,参考手册 # 使用方法: 解压 【poi-ooxml-***.jar中文文档.zip】,再解压其中的 【poi-ooxml-***-javadoc-API文档-中文(简体)版.zip】,双击 【index.html】 文件,即可用浏览器打开、进行查看。 # 特殊说明: ·本文档为人性化翻译,精心制作,请放心使用。 ·只翻译了该翻译的内容,如:注释、说明、描述、用法讲解 等; ·不该翻译的内容保持原样,如:类名、方法名、包名、类型、关键字、代码 等。 # 温馨提示: (1)为了防止解压后路径太长导致浏览器无法打开,推荐在解压时选择“解压到当前文件夹”(放心,自带文件夹,文件不会散落一地); (2)有时,一套Java组件会有多个jar,所以在下载前,请仔细阅读本篇描述,以确保这就是你需要的文件; # Maven依赖: ``` <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi-ooxml</artifactId> <version>***</version> </dependency> ``` # Gradle依赖: ``` Gradle: implementation group: 'org.apache.poi', name: 'poi-ooxml', version: '***' Gradle (Short): implementation 'org.apache.poi:poi-ooxml:***' Gradle (Kotlin): implementation("org.apache.poi:poi-ooxml:***") ``` # 含有的 Java package(包)(此处仅列举3个): ``` org.apache.poi.ooxml org.apache.poi.ooxml.dev org.apache.poi.ooxml.extractor ...... ``` # 含有的 Java class(类)(此处仅列举3个): ``` org.apache.poi.ooxml.POIXMLDocument org.apache.poi.ooxml.POIXMLDocumentPart org.apache.poi.ooxml.POIXMLDocumentPart.RelationPart ...... ```
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值