JAVA笔记-如何将百万级数据高效的导出到Excel表单
使用JAVA有没有什么办法导出百万级的数据到Excel工作表。
ps: 首先科普一下基础知识
Excel 2003及以下的版本。一张表最大支持65536行数据,256列。也就是说excel2003完全不可能满足百万数据导出的需求。
Excel 2007-2010版本。一张表最大支持1048576行,16384列;
笔者使用的是office 2010,更高的版本笔者没有使用过,暂时无法判断。
由此看来百万级的数据量对Excel自身已经是属于接近极限的程度。
假如我们有更大的需求怎么办呢?
既然单表支持最大是104w条数据,那么更大的需求量我们就只能通过程序级分表操作的方式来实现了。O(∩_∩)O哈哈~
对于操作Excel的类库。笔者其实了解的并不是很多。只是很早以前使用过POI这个类库,感觉很不错。于是决定从它入手。看看POI有没有什么比较有效的好点的解决办法。由于笔者以前使用的POI版本比较低。而且使用于excel 2003版本。所以遇到了不少问题。
编辑器: Intellij IDEA 13.2
类库需求: POI-3.10-Final
1 <dependency> 2 <groupId>org.apache.poi</groupId> 3 <artifactId>poi</artifactId> 4 <version>3.10-FINAL</version> 5 </dependency>
新建一个Maven项目。
根据笔者以往的经验,直接使用POI写了一份代码。执行的时候直接报错了。
1 public static void Excel2003Operate(String filePath) throws Exception { 2 HSSFWorkbook hssfWorkbook = new HSSFWorkbook(new FileInputStream(new File(filePath))); 3 HSSFSheet sheet = hssfWorkbook.getSheetAt(0); 4 for (int i = 0; i < 10000; i++) { 5 HSSFRow hssfRow = sheet.createRow(i); 6 for (int j = 0; j < 10; j++) { 7 HSSFCellUtil.createCell(hssfRow, j, String.valueOf(Math.random())); 8 } 9 } 10 FileOutputStream out = new FileOutputStream("workbook.xlsx"); 11 hssfWorkbook.write(out); 12 out.close(); 13 }
1 Connected to the target VM, address: '127.0.0.1:62382', transport: 'socket' 2 Exception in thread "main" org.apache.poi.poifs.filesystem.OfficeXmlFileException: The supplied data appears to be in the Office 2007+ XML. You are calling the part of POI that deals with OLE2 Office Documents. You need to call a different part of POI to process this data (eg XSSF instead of HSSF) 3 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:131) 4 at org.apache.poi.poifs.storage.HeaderBlock.<init>(HeaderBlock.java:104) 5 at org.apache.poi.poifs.filesystem.POIFSFileSystem.<init>(POIFSFileSystem.java:128) 6 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:342) 7 at org.apache.poi.hssf.usermodel.HSSFWorkbook.<init>(HSSFWorkbook.java:323) 8 at dev.tinyz.excel.POIUtil.Excel2003Operate(POIUtil.java:23) 9 at dev.tinyz.excel.Main.main(Main.java:16) 10 Disconnected from the target VM, address: '127.0.0.1:62382', transport: 'socket'
运行直接报错了。仔细看了报错信息之后发现。POI要操作excel 2007及以上的版本需要使用XSSF来代替上面代码的HSSF。
发现类库居然没有XSSF相关的类。着笔者傻眼了说。于是去POI官网查看。发现完整的POI类库包含的内容很多。于是详细了解了一下每个部分的具体作用:
poi-ooxml和poi-ooxml-schemas是poi对2007及以上版本的扩充。于是在maven依赖中增加:
1 <dependency> 2 <groupId>org.apache.poi</groupId> 3 <artifactId>poi-ooxml</artifactId> 4 <version>3.10-FINAL</version> 5 </dependency> 6 <dependency> 7 <groupId>org.apache.poi</groupId> 8 <artifactId>poi-ooxml-schemas</artifactId> 9 <version>3.10-FINAL</version> 10 </dependency>
赶紧修改自己的代码。实现了支持Excel 2010版本。瞬间有种大功告成的感觉,有木有。。O(∩_∩)O哈哈~。好有成就感的说。
1 public static void Excel2007AboveOperateOld(String filePath) throws IOException { 2 XSSFWorkbook workbook = new XSSFWorkbook(new FileInputStream(new File(filePath))); 3 // 获取第一个表单 4 Sheet first = workbook.getSheetAt(0); 5 for (int i = 0; i < 100000; i++) { 6 Row row = first.createRow(i); 7 for (int j = 0; j < 11; j++) { 8 if(i == 0) { 9 // 首行 10 row.createCell(j).setCellValue("column" + j); 11 } else { 12 // 数据 13 if (j == 0) { 14 CellUtil.createCell(row, j, String.valueOf(i)); 15 } else 16 CellUtil.createCell(row, j, String.valueOf(Math.random())); 17 } 18 } 19 } 20 // 写入文件 21 FileOutputStream out = new FileOutputStream("workbook.xlsx"); 22 workbook.write(out); 23 out.close(); 24 }
赶紧运行跑起来。第一次测试写入1w条数据。耗时8秒多点。感觉写入速度好慢,1w条8秒,100w。。我的天。这效率完全不能接受。于是测试10w,看看测试一下是不是真的写入速度过慢。测试结果让人崩溃。
1 Cast time : 49699
测试导出10w条数据到excel耗时将近50秒。于是这种方式被暂时放弃。成就感瞬间被打落在地。
再次回到POI的官网。http://poi.apache.org/spreadsheet/index.html
官方提到自POI3.8版本开始提供了一种SXSSF的方式,用于超大数据量的操作。于是...
原文:
SXSSF is an API-compatible streaming extension of XSSF to be used when very large spreadsheets have to be produced...
马上开动修改代码。代码如下:
1 public static void Excel2007AboveOperate(String filePath) throws IOException { 2 XSSFWorkbook workbook1 = new XSSFWorkbook(new FileInputStream(new File(filePath))); 3 SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(workbook1, 100); 4 // Workbook workbook = WorkbookFactory.create(new FileInputStream(new File(filePath))); 5 Sheet first = sxssfWorkbook.getSheetAt(0); 6 for (int i = 0; i < 100000; i++) { 7 Row row = first.createRow(i); 8 for (int j = 0; j < 11; j++) { 9 if(i == 0) { 10 // 首行 11 row.createCell(j).setCellValue("column" + j); 12 } else { 13 // 数据 14 if (j == 0) { 15 CellUtil.createCell(row, j, String.valueOf(i)); 16 } else 17 CellUtil.createCell(row, j, String.valueOf(Math.random())); 18 } 19 } 20 } 21 FileOutputStream out = new FileOutputStream("workbook.xlsx"); 22 sxssfWorkbook.write(out); 23 out.close(); 24 }
多次运行测试。查看数据
1 Cast time : 11604
看到数据的瞬间感觉,哇塞。好给力的说。居然从将近50秒缩短带11秒。。。
为什么都是代码差距就这么大呢?
原来,SXSSF实现了一套自动刷入数据的机制。当数据数量达到一定程度时(用户可以自己设置这个限制)。像文本中刷入部分数据。这样就缓解了程序运行时候的压力。达到高效的目的。O(∩_∩)O哈哈~
再一次测试单表写入100w条数据。
1 Cast time : 87782
将近90秒就完成了100w条数据的写入。O(∩_∩)O哈哈~。 虽然看上去依旧有一点慢。但是考虑到数据量这样的耗时,想来已经是可以接受的了。100w条数据生成的Excel表单居然有136mb。打开就这个文档都花了不少时间。哈哈
晒一下成就:
源码下载:http://pan.baidu.com/s/1bnw9pYB
笔者能力有限。暂时只是使用POI类库实现了相对高效的批量写入。假如有更好的类库或者是方法的朋友。欢迎留言分享。多谢指点。。O(∩_∩)O哈哈~
作者:TinyZ
出处:http://www.cnblogs.com/zou90512/
关于作者:努力学习,天天向上。不断探索学习,提升自身价值。记录经验分享。
本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文链接
如有问题,可以通过 zou90512@126.com 联系我,非常感谢。
JAVA笔记-如何将百万级数据高效的导出到Excel表单相关推荐
- java实现如何将百万级数据高效的导出到Excel表单
ps: 首先科普一下基础知识 Excel 2003及以下的版本.一张表最大支持65536行数据,256列.也就是说excel2003完全不可能满足百万数据导出的需求. Excel 2007-2010版 ...
- java导出动态excel表单----表头和内容都为动态
数据表 CREATE TABLE `f_form` (`id` bigint(32) NOT NULL AUTO_INCREMENT COMMENT '主键',`org_id` bigint(32) ...
- java 动态导出excel表单 无模板文件下载
java 动态导出excel表单 无模板文件下载 public ResponseEntity<byte[]> exportStanding(@PathVariable Long signu ...
- java 动态导出excel表单 无模板本地生成
java 动态导出excel表单 无模板本地生成 这里使用的是alibaba的公共类excelWriter,注意在pom文件中要引入easyExcel的依赖 public void exportExc ...
- Java使用FreeMarker自动生成Word文档(带图片和表单)
Java使用FreeMarker自动生成Word文档(带图片和表单) 1 背景 2 目标效果 3 创建Word模板 3.1 创建模板文档 3.2 转换模板文档 3.3 处理模板文档中的占位符 3.4 ...
- Java入力项目无法设定到form_html中关于form与表单提交操作的资料集合
原标题:html中关于form与表单提交操作的资料集合 这里我们介绍一下form元素与表单提交方面的知识. form元素 form元素的DOM接口是HTMLFormElement,继承自HTMLEle ...
- java客户端重复请求_Java后台防止客户端重复请求、提交表单实现原理
Java后台防止客户端重复请求.提交表单实现原理 发布于 2021-1-8| 复制链接 摘记: 这篇文章主要介绍了Java后台防止客户端重复请求.提交表单实现原理,文中通过示例代码介绍的非常详细,对大 ...
- extjs 提交表单给php,JavaScript_Extjs学习笔记之二 初识Extjs之Form,Extjs中的表单组件是Ext.form.Basic - phpStudy...
Extjs学习笔记之二 初识Extjs之Form Extjs中的表单组件是Ext.form.BasicForm,不过最简单最常用的是Ext.form.FormPanel控件,它继承自Panel,具有一 ...
- java sql编辑器 动态报表 数据库备份还原 quartz定时任务调度 自定义表单 java图片爬虫...
A代码编辑器,在线模版编辑,仿开发工具编辑器,pdf在线预览,文件转换编码 B 集成代码生成器 [正反双向](单表.主表.明细表.树形表,快速开发利器)+快速表单构建器 freemaker模版技术 , ...
最新文章
- Android中的“再按一次返回键退出程序”实现
- Java中long和Long有什么区别
- 装了BT5后要做的几件事
- 对象的当前状态使该操作无效 说明: 执行当前 Web 请求期间,出现未处理的异常。...
- 接着做!一往无前!冲!就是我的信条!
- redis的redisvCommand的%b
- 【Python】Python实战从入门到精通之一 -- 教你深入理解Python中的变量和数据类型
- LCD1602(以51单片机为例)
- virtualbox 网络配置
- 语音识别(LSTM+CTC)
- 阶段1 语言基础+高级_1-3-Java语言高级_08-JDK8新特性_第1节 常用函数接口_4_使用Lambda优化日志案例...
- 集合Collections,List
- ios8 gps定位不好用
- Java学习笔记之设计模式(5)装饰者模式
- 如何从12306网站下载自己喜欢的手机铃声
- android方法不混淆,Android 混淆时不混淆注解方法
- 百度云网盘批量复制文件,在线复制到每个文件夹中PC版
- 利用input[type=range]制作一个简易的音乐播放器
- mac php 单元测试,PHPUnit单元测试
- 当金融科技遇上云原生,蚂蚁金服是怎么做安全架构的?