【Apache POI】Excel操作(四):Excel大数据量的写入
迷茫代表着你身边还有选择,焦虑意味着你手上还有时间。
有目录,不迷路
- 前言
- 超量数据
- 速率比较
- 原因剖析
- 超级版本大救星
- 往期回顾
前言
之前在下面这期Excel操作:
【Apache POI】Excel操作(一):Excel本地写入基本操作的实现
中说到Excel有两个版本,分别是HSSF以及XSSF:
以及他们之间的两点不同:
第一,后缀名不同:
第二,最多写入的数据量也就是数据行数不同:
- 03版本的
.xls
Excel文件最多为65536行。 - 07版本的
.xlsx
Excel文件则最多为1048576行,刚好是65536也就是03版本的16倍。
而我们如果点开Excel的工作簿Workbook
,我们会发现这是一个接口。而这个接口下面有三个实现类分别是:HSSFWorkbook、XSSFWorkbook以及SXSSFWorkbook。
也就是说Excel似乎是有着三个版本:
HSSF
版本XSSF
版本SXSSF
版本
那么,多出来的这个SXSSF
版本有什么用呢?以及这几个版本之间对于程序而言有什么具体的区别?
本期博客为你揭晓答案!!!
超量数据
本期博客所需环境如依赖等已经在以下这期博客中介绍过了,就不多加赘述:
【Apache POI】Excel操作(一):Excel本地写入基本操作的实现
接着上面既然我们说到03版本的.xls
Excel文件最多为65536行以及07版本的.xlsx
Excel文件则最多为1048576行,那我们试着来创建一下超过数据限制的行数(当然,这也是写入过量数据的前奏):
03版:
/*** 03版写入超量的数据*/@Testpublic void write03ExcessData(){// 创建工作簿Workbook workbook = new HSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 创建第65537行sheet.createRow(65536);}
运行得:
即超过了(0…65535)的行数限制:
java.lang.IllegalArgumentException: Invalid row number (65536) outside allowable range (0..65535)
07版:
/*** 07版写入超量的数据*/@Testpublic void write07ExcessData(){// 创建工作簿Workbook workbook = new XSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 创建第65537行sheet.createRow(1048576);}
运行得:
即超过了(0…1048575)的行数限制:
java.lang.IllegalArgumentException: Invalid row number (1048576) outside allowable range (0..1048575)
速率比较
既然本期博客讲的是大数据量的写入,那么我们必然要关心一个问题:那就是时间问题!!! 作为一名开发,你总不可能在写入数据量多的时候,导出个Excel让用户等它个地老天荒吧!
那就让我们分别来测试一下
03版本
和07版本
写入65536行数据的耗时吧!
03版写入65536行数据耗时测试:
/*** 03版本写入65536行数据*/@Testpublic void write03BigData() throws Exception {// 获取当前系统的毫秒数long startTime = System.currentTimeMillis();// 创建工作簿Workbook workbook = new HSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 外层for循环分别创建65536行for (int rowNumber = 0; rowNumber < 65536; rowNumber++) {// 创建第 rowNumber+1 行Row row = sheet.createRow(rowNumber);// 内层循环分别创建11列并写入列的索引for (int cellNumber = 0; cellNumber < 11; cellNumber++) {row.createCell(cellNumber).setCellValue(cellNumber);}}// 生成流FileOutputStream out = new FileOutputStream(PATH + File.separator + "03BigDataTest.xls");// 写入workbook.write(out);// 关流out.close();System.out.println("excel生成完毕!!!");// 获取当前系统的毫秒数long endTime = System.currentTimeMillis();// 计算耗时并打印在控制台System.out.println("耗时: " + (double)(endTime - startTime)/1000 + "s");}
运行可以得出耗时为2.29秒:
那我们再来看看07版本选手的表现吧!
07版写入65536行数据耗时测试:
/*** 07版本写入65536行数据*/@Testpublic void write07BigData() throws Exception {// 获取当前系统的毫秒数long startTime = System.currentTimeMillis();// 创建工作簿Workbook workbook = new XSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 外层for循环分别创建65536行for (int rowNumber = 0; rowNumber < 65536; rowNumber++) {// 创建第 rowNumber+1 行Row row = sheet.createRow(rowNumber);// 内层循环分别创建11列并写入列的索引for (int cellNumber = 0; cellNumber < 11; cellNumber++) {row.createCell(cellNumber).setCellValue(cellNumber);}}// 生成流FileOutputStream out = new FileOutputStream(PATH + File.separator + "07BigDataTest.xlsx");// 写入workbook.write(out);// 关流out.close();System.out.println("excel生成完毕!!!");// 获取当前系统的毫秒数long endTime = System.currentTimeMillis();// 计算耗时并打印在控制台System.out.println("耗时: " + (double)(endTime - startTime)/1000 + "s");}
运行可以得出耗时为12.271秒:
What???同样的数据量,07版本耗时竟然是03版本的五六倍?要是在数据量更多的情况下写出07版本的代码,那还不是连夜被老板叫过去加班吗?而且03版本的数据量比较多的情况下还不能用,简直就是屋落偏逢连夜雨。
原因剖析
那么为什么03版的HSSF和07版的XSSF会有那么大的差距呢?
原来,03版的HSSF在写入过程中,是将数据写入到缓存中,然后再一次性写入磁盘,所以HSSF的速率很快。当然,他的缺点也很明显,就是能够写入的数据量不够大!!!
而,07版本XSSF是通过内存加载数据,非常的消耗内存,速率也比较低下。虽然XSSF理论上能够写入1048576行数据,但是它也很容易发生内存溢出,如果我们试着用XSSF
来写入一百万条数据:
/*** 07版本写入一百万行数据*/@Testpublic void write07BigData() throws Exception {// 获取当前系统的毫秒数long startTime = System.currentTimeMillis();// 创建工作簿Workbook workbook = new XSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 外层for循环分别创建65536行for (int rowNumber = 0; rowNumber < 999999; rowNumber++) {// 创建第 rowNumber+1 行Row row = sheet.createRow(rowNumber);// 内层循环分别创建11列并写入列的索引for (int cellNumber = 0; cellNumber < 11; cellNumber++) {row.createCell(cellNumber).setCellValue(cellNumber);}}// 生成流FileOutputStream out = new FileOutputStream(PATH + File.separator + "07BigDataTest.xlsx");// 写入workbook.write(out);// 关流out.close();System.out.println("excel生成完毕!!!");// 获取当前系统的毫秒数long endTime = System.currentTimeMillis();// 计算耗时并打印在控制台System.out.println("耗时: " + (double)(endTime - startTime)/1000 + "s");}
然后,成功内存溢出,即:java.lang.OutOfMemoryError: Java heap space:
超级版本大救星
那么,现在问题来了:就目前而言,Excel大数据量的写入如20万条数据。不能用03版本,只能用07版本,但是07版本XSSF的效率低下,并且容易发生内存溢出。那么,我们应该怎么办呢?
这个时候,本文开始提出的另一个版本-SXSSF,也就是 Super - XSSF,XSSF超级版就横空出世了:
我们再来测一下SXSSF写入65536行数据的耗时:
/*** SXSSF版本写入65536行数据耗时统计*/@Testpublic void writeSXSSFBigData() throws Exception {// 获取当前系统的毫秒数long startTime = System.currentTimeMillis();// 创建工作簿Workbook workbook = new SXSSFWorkbook();// 创建工作表Sheet sheet = workbook.createSheet();// 外层for循环分别创建65536行for (int rowNumber = 0; rowNumber < 65536; rowNumber++) {// 创建第 rowNumber+1 行Row row = sheet.createRow(rowNumber);// 内层循环分别创建11列并写入列的索引for (int cellNumber = 0; cellNumber < 11; cellNumber++) {row.createCell(cellNumber).setCellValue(cellNumber);}}// 生成流FileOutputStream out = new FileOutputStream(PATH + File.separator + "07BigDataTestSuper.xlsx");// 写入workbook.write(out);// 关流out.close();// 清除临时文件((SXSSFWorkbook)workbook).dispose();System.out.println("excel生成完毕!!!");// 获取当前系统的毫秒数long endTime = System.currentTimeMillis();// 计算耗时并打印在控制台System.out.println("耗时: " + (double)(endTime - startTime)/1000 + "s");}
代码与07版本的其实只有两处不同:
第一,创建的对象:
// 创建工作簿
Workbook workbook = new SXSSFWorkbook();
第二,由于SXSSF会生成临时文件,所以需要清除临时文件:
// 清除临时文件
((SXSSFWorkbook)workbook).dispose();
最后运行得:
从12秒多到3秒多,节省了近3倍的时间,简直是质的飞越!
而,为什么SXSSF版本比XSSF版本速率快这么多呢?
原来,SXSSF在写入过程中会产生临时文件,它默认有100条记录保存在内存中,如果超过一百条,则在最前面的数据会被写入到临时文件里。
当然,我们也可以自定义内存中保存记录的数量,如我想保存120条:
// 创建工作簿
Workbook workbook = new SXSSFWorkbook(120);
好了,到目前为止Apach POI的写入操作就结束了。接下来的博客将给大家带来Apach POI对Excel的读取操作以及EasyExcel对Excel的读写操作,感兴趣的小伙伴可以关注我哦!
往期回顾
以下是往期Excel操作的回顾:
【Apache POI】Excel操作(一):Excel本地写入基本操作的实现
【Apache POI】Excel操作(二):Excel本地写入基本操作的实现(进阶版)
【Apache POI】Excel操作(三):Excel在浏览器端即Web端写入操作的实现
参考资料:【狂神说Java】POI及EasyExcel一小时搞定通俗易懂
【Apache POI】Excel操作(四):Excel大数据量的写入相关推荐
- Java 使用 POI 操作 Excel(反射,大数据量)
Apache POI 基本介绍 Apache POI 是 Apache 软件基金会提供的 100% 开源库.支持 Excel 库的所有基本功能. 图片来源:易百教程 基本概念 在 POI 中,Work ...
- 大数据导出excel大小限制_EXCEL大数据量导出的解决方案
将web页面上显示的报表导出到excel文件里是一种很常见的需求.润乾报表的类excel模型,支持excel文件数据无失真的导入导出,使用起来非常的方便.然而,当数据量较大的情况下,excel本身的支 ...
- 大数据导出excel大小限制_大数据量导出Excel的方案
测试共同条件: 数据总数为110011条,每条数据条数为19个字段. 电脑配置为:P4 2.67GHz,1G内存. 一.POI.JXL.FastExcel比较 POI.JXL.FastExcel均为j ...
- excel导入sqlserver数据库大数据量,可每秒控制数量
数据库代码 USE [Test] GO /****** Object: Table [dbo].[Table_1] Script Date: 11/07/2017 17:27:29 ***** ...
- python解析excel内存溢出_phpExcel大数据量情况下导出内存溢出解决
1.将单元格数据序列化后保存在内存中 PHPExcel_CachedObjectStorageFactory::cache_in_memory_serialized; 2.将单元格序列化后再进行Gzi ...
- Excel文件导出总结,包含大数据量的分批导出方式
文章目录 需求背景 参考内容 导出方式 代码实现 Excel4J 普通导出 POI原生方式 普通导出 大数据量分批导出 依赖版本 实现思路 POI工具类 数据写入 调用测试 测试结果 一个小意外 Ea ...
- Apache POI和EasyExcel 第三集:Apache POI的Excel大数据量写入(分为03版的xls、07版的xlsx、升级版SXSSF)
Apache POI和EasyExcel 第三集:Apache POI的Excel大数据量写入(分为03版的xls.07版的xlsx.升级版SXSSF) 一.结果 我的03跑了1.204秒,07跑了5 ...
- Apache POI组件操作Excel,制作报表(四)
Apache POI组件操作Excel,制作报表(四) 博客分类: 探索实践 ExcelApacheSpringMVCServlet 上一篇我们介绍了如何制作复杂报表的分析和设计,本篇结合Sprin ...
- Java操作大数据量Excel导入导出万能工具类(完整版)
Java操作大数据量Excel导入导出万能工具类(完整版) 转载自:https://blog.csdn.net/JavaWebRookie/article/details/80843653 更新日志: ...
最新文章
- lgg6 android 9,【LGG6评测】18:9奇葩比例没采用骁龙835 LG G6解析_LG G6_手机评测-中关村在线...
- 600 imp oracle_oracle中exp,imp的使用详解
- 李青源:高清体验和带宽节省,瞄准方向深耕
- 已知矩阵 matlab,在MATLAB中,已知矩阵A,那么A(:,2:end)表示
- 用数据库的方式编辑上一页 下一页
- Keil(MDK-ARM-STM32)系列教程(二)工具栏详细说明
- EasyUI三级联动下拉框
- Windows系统安装Mysql前运行库依赖
- Python数据可视化三部曲之 Pyecharts 从上手到上头
- Chrome:下载Chrome网上应用店扩展程序crx
- Node.JS全开源B2C商城
- Matter 研讨会回顾(第二期)|乐鑫 Matter SDK 开发平台介绍和使用
- 4、网络嗅探器的设计与实现
- 《德米安》从那以后伤口很痛,但偶尔我会找到钥匙,沉入心底
- 【学习笔记】SBT学习笔记
- #5.2探讨时空同时考虑的相关理论的软肋
- python学习笔记(一)数据处理
- 数字图像处理-美图秀秀:瘦脸算法
- GA-PH67-UD3-B3换主板
- bp神经网络实验报告郑航_bp神经网络实验报告
热门文章
- 用JAVA输出等腰三角形(实心、空心)
- 浅拷贝与深拷贝的区别(详解)
- sql查询出1到12月的数据形成报表
- Keil uVision5 针对特定单片机型号的环境配置方法
- 【深度之眼】kesci二分类算法大赛之初体验
- 报错InvalidArgumentError (see above for traceback): Restoring from checkpoint failed
- Python爬虫之公交路线及公交站坐标获取
- Xiaojie雷达之路---详解ADCBuf driver源码
- asp中文编码和php编码的区别,ASP关于编码的几个有用的函数小结(utf8)
- 2021年危险化学品经营单位安全管理人员考试内容及危险化学品经营单位安全管理人员考试总结