POI-HSSF和POI-XSSF / SXSSF-用于访问Microsoft Excel格式文件。
那么HSSF 是针对(.xls)文件格式 的解析和导出操作类。XSSF可以同时解析(.xls和.xlsx)两种类型。
从3.8-beta3开始,POI提供了基于XSSF的低内存占用的SXSSF API。
SXSSF是XSSF的API兼容流扩展,可用于必须生成非常大的电子表格且堆空间有限的情况。SXSSF通过限制对滑动窗口内的行的访问来实现其低内存占用,而XSSF允许对文档中的所有行进行访问。不再存在于窗口中的较旧的行由于被写入磁盘而变得不可访问。
在自动刷新模式下,可以指定访问窗口的大小,以在内存中保留一定数量的行。当达到该值时,创建额外的一行将导致具有最低索引的行从访问窗口中删除并写入磁盘。或者,可以将窗口大小设置为动态增长。可以根据需要通过显式调用flushRows(int keepRows)定期对其进行修剪。
由于实现的流性质,与XSSF相比存在以下限制:
- 在某个时间点只能访问有限数量的行。
- 不支持Sheet.clone()。
- 不支持公式评估
附上一张POI官方的截图,可以看到 eventmodel 模式下采用流式处理的方式减少了CPU及内存的消耗,当然也只能进行读操作。
针对大数据写操作,POI同样也实现了运用了缓冲流来处理,同样对CPU和内存消耗很低。但是这种流处理的模式也有弊端就是实现的功能有限例如formula evaluation,shift rows,cell comments 都不支持。具体信息见下图。当然easypoi再 流处理的基础上加上poi没有实现的功能。见下一篇文章
readUtils
package com.qtopay.decode.tools.common.excel;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.openxml4j.exceptions.OpenXML4JException;
import org.apache.poi.openxml4j.opc.OPCPackage;
import org.apache.poi.xssf.eventusermodel.ReadOnlySharedStringsTable;
import org.apache.poi.xssf.eventusermodel.XSSFReader;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler;
import org.apache.poi.xssf.eventusermodel.XSSFSheetXMLHandler.SheetContentsHandler;
import org.apache.poi.xssf.model.StylesTable;
import org.apache.poi.xssf.usermodel.XSSFComment;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.xml.sax.InputSource;
import org.xml.sax.SAXException;
import org.xml.sax.XMLReader;
import org.xml.sax.helpers.XMLReaderFactory;
/**
* excel 解析
* @author yang
* @version $Id: ExcelReadUtil.java, v 0.1 2020年5月28日 上午11:36:28 yang Exp $
*/
public class ExcelReadUtil {
private static final Logger logger = LoggerFactory.getLogger(ExcelReadUtil.class);
/**
* 表格默认处理器
*/
private ISheetContentHandler contentHandler = new DefaultSheetHandler();
/**
* 读取数据
*/
private List<String[]> datas = new ArrayList<String[]>();
/**
* 转换表格,默认为转换第一个表格
* @param stream
* @return
* @throws InvalidFormatException
* @throws IOException
* @throws ParseException
*/
public ExcelReadUtil parse(InputStream stream) throws InvalidFormatException, IOException, ParseException {
return parse(stream, 1);
}
/**
*
* @param stream
* @param sheetId:为要遍历的sheet索引,从1开始
* @return
* @throws InvalidFormatException
* @throws IOException
* @throws ParseException
*/
public ExcelReadUtil parse(InputStream stream, int sheetId) throws InvalidFormatException, IOException, ParseException {
// 每次转换前都清空数据
datas.clear();
// 打开表格文件输入流
OPCPackage pkg = OPCPackage.open(stream);
try {
// 创建表阅读器
XSSFReader reader;
try {
reader = new XSSFReader(pkg);
} c