Apache-poi SXSSFWorkbook 流处理

在POI导出的时候我们需要根据不同的excel版本,以及预计最大数据量来选择相应的POI工具类.

POI用于操作Excel的对象都是实现了Workbook接口的类.

Workboot是创建Excel对象或Sheet等的顶级对象,有四个子类.

在这里插入图片描述

HSSFWorkbook

  1. 操作Excel2003以前(包括2003)的版本,扩展名是.xls

  2. 此种方式的局限就是导出的行数至多为65535行,超出65536条后系统就会报错。此方式因为行数不足七万行所以一般不会发生内存不足的情况(OOM)

XSSFWorkbook

  1. 操作Excel2007后的版本,扩展名是.xlsx
  2. 这种形式的出现是为了突破HSSFWorkbook的65535行局限。对应的是excel2007(1048576行,16384列)扩展名为“.xlsx”,最多可以导出104万行,不过这样就伴随着一个问题—OOM内存溢出,原因是所创建的book,sheet,row等对象是在内存中的,并没有持久化到磁盘.大数据量情况下项目的运行内存根本不够.

SXSSFWorkbook

  1. 操作Excel2007后的版本,扩展名是.xlsx
  2. 对于大型excel文件的创建,一个关键问题就是,要确保不会内存溢出。其实,就算生成很小的excel(比如几Mb),它用掉的内存是远大于excel文件实际的size的。再加上单元格样式之类的,那它占用的内存就更多了。对于大型excel的创建且不会内存溢出的,就只有SXSSFWorkbook了。它的原理很简单,用硬盘空间换内存(就像hash map用空间换时间一样)。
    SXSSFWorkbook是streaming版本的XSSFWorkbook,它只会保存最新的excel rows在内存里供查看,在此之前的excel rows都会被写入到硬盘里(Windows电脑的话,是写入到C盘根目录下的temp文件夹)。被写入到硬盘里的rows是不可见的/不可访问的。只有还保存在内存里的才可以被访问到。

SXSSFWorkbookWithCustomZipEntrySource

是SXSSFWorkbook的子类,在构建SXSSFWorkbook对象的时候可以配置是否压缩磁盘中的excel.压缩后磁盘的空间使用率会大大减少,但是队导出的性能就有所影响

重点说下SXSSFWorkbook的相关操作

官方介绍翻译后大致如下:

SXSSF是一个与API兼容的流扩展,在需要生成非常大的电子表格时使用,堆空间有限。SXSSF通过限制对滑动窗口中的行的访问来实现其低内存占用,而XSSF允许访问文档中的所有行。当将旧行写入磁盘时,不再在窗口中的旧行变得不可访问

SXSSFWorkbook构造器:
1.默认构造器

在这里插入图片描述

用默认的行窗口大小构造一个新的Workboot对象,默认值为100
在这里插入图片描述

2.使用现有模板或者需要在之前Excel后追加

在这里插入图片描述

因为SXSSF是XSSF的一个与API兼容的,所以可以用XSSFWorkbook来构建新的模板样式对象,也是没有设置滑动窗口的大小,所以也是默认100.

3.兼容现有模板并且制定滑动窗口大小

在这里插入图片描述

rowAccessWindowSize: 窗口大小
可以根据环境配置来设置窗口大小,过大会消耗内存,过小会频繁stream操作.
设置为-1表示不限制内存存储的row数量,若需要刷新在磁盘需手动调用output的flush(),注意:若已刷新不在内存的row不可以通过getRow()来获取了

4.兼容现有模板,自定义窗口大小并且设置临时文件GZIP压缩

在这里插入图片描述

5.兼容现有模板,自定义窗口大小并且设置临时文件是否GZIP压缩,设置是否要采用共享字符串表

在这里插入图片描述

SharedStringsTable:共享字符串表,当前Workbot中的字符串缓存
根据实际情况来设置,若导出的数据中有大量重复的字符串,则可以设置开启.

引用SharedStringsTable注释:

Consider for example a workbook summarizing information for cities within
<various countries. There may be a * column for the name of the country, a column for the name of each city in that country, and a column * containing the data for each city. In this case the country name is repetitive, being duplicated in many cells. * In many cases the repetition is extensive, and a tremendous savings is realized by making use of a shared string * table when saving the workbook. When displaying text in the spreadsheet, the cell table will just contain an * index into the string table as the value of a cell, instead of the full string.

例如,考虑一个工作簿,它汇总了各个国家/地区中城市的信息。国家名称可能带有某列,该国家/地区中每个城市的名称均带有某列,而每个城市的数据则带有某列。在这种情况下,国家/地区名称是重复的,在许多单元格中重复。 在许多情况下,重复是广泛的,并且在保存工作簿时通过使用共享字符串表可以实现巨大的节省。在电子表格中显示文本时,单元格表将只在字符串表中包含一个索引作为单元格的值,而不是完整的字符串。

6.只设置窗口大小
在这里插入图片描述

若没有则创建一个新的XSSFWorkbook对象
以上所有构造都是调用的此构造
👇👇👇👇👇👇
在这里插入图片描述

介绍完所有构造,对SXSSFWorkbook的功能作用以及用法有大致了解.

之前说过,如果内存冲存储的row数据超过我们设置的窗口阈值,则会刷新在磁盘的临时文件.可以设置临时文件在磁盘的路径:
在这里插入图片描述

默认是系统配置的tmp路径
在这里插入图片描述

在这里插入图片描述

也可以自定义配置临时路径
在这里插入图片描述

调用TempFile的setTempFileCreationStrategy()

小补充:
刚开始用SXSSFWorkbook的时候在想如果临时文件过多会怎么办.会不会自动删除临时文件或者需要我们定时清除.
在这里插入图片描述

Workboot对象会在write后帮我们释放磁盘空间

简单示例:

	//创建现有模板对象
	XSSFWorkbook xss = null;
	//Stream处理模板对象
	SXSSFWorkbook exl = null;
	FileOutputStream out = null;
	try(FileInputStream input = new FileInputStream(new File(filePath))) {
    	xss = new XSSFWorkbook(input);
    	//构建SXSSF,设置模板和内存保留行数
   		 exl = new SXSSFWorkbook(xss,100);
    	//更变临时文件目录
    	TempFile.setTempFileCreationStrategy(new DefaultTempFileCreationStrategy(new File("E:\\Temp")));
    	//获取Sheet
    	SXSSFSheet sheet = exl.getSheet("Sheet");
   		//省略写入excel相关代码
   		......

		//写入execl
		out = new FileOutputStream(filePath);
    	exl.write(outputStream1);
	} catch (Exception ex) {
  	 LOGGER.error("Exception is : {}",  ex);
	} finally {
    	try {
	        if (exl != null) {
	            exl.close();
	        }
	        if (out != null) {
	            out.close();
	        }
	        if (xss != null){
	            xss.close();
	        }
	    } catch (IOException ex) {
	        ex.printStackTrace();
	    }
}
  • 3
    点赞
  • 13
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值