今天,一朋友问我使用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://www.cnblogs.com/zou90512/p/3989450.html

JAVA笔记-如何将百万级数据高效的导出到Excel表单的更多相关文章

  1. Java导出Pdf格式表单

    前言   作为开发人员,工作中难免会遇到复杂表单的导出,接下来介绍一种通过Java利用模板便捷导出Pdf表单的方式 模拟需求   需求:按照下面格式导出pdf格式的学生成绩单 准备工作 Excel软件 ...

  2. java中的数据导出到Excel表中

    整个项目中导出数据到.Excel的源码 import java.io.BufferedOutputStream; import java.io.FileInputStream; import java ...

  3. Java 添加、删除Excel表单控件

    通过表单控件,用户可以快速地将数据填写到模板文档中,轻松引用单元格数据并与其进行交互.本文通过Java代码示例介绍如何在Excel表格中添加表单控件,包括文本框.单选按钮.复选框.组合框.微调按钮等: ...

  4. BI之路学习笔记2--SSIS/ETL设计练习三:《DB->定期生成excel表》

    上次笔记记到,用sql任务给参数赋值,映射到变量,然后把数据流任务放到序列容器中进行执行,可以定期生成excel, 现在的问题是: 在EXCEL目标编辑过程中,必须选定某一个特定的excel目标,这样 ...

  5. 前端笔记之React(二)组件内部State&React实战&表单元素的受控

    一.组件内部的State 1.1 state state叫状态,是每一个类式组件都有的属性,但函数式组件,没有state. state是一个对象,什么值都可以定义. 在任何类式组件的构造函数中,可以用 ...

  6. 使用jQuery快速高效制作网页交互特效---表单校验

    表单基本验证技术 为什么需要表单验证 减轻服务器的压力 保证输入的数据符合要求 常用的表单验证 1.日期格式 2.表单元素是否为空 3.用户名和密码 4.E-mail地址 5.身份证号码 表单选择器 ...

  7. PHP百万级数据导出方案(多csv文件压缩)

    本文转自网络仅供学习之用 概述: 最近公司项目要求把数据除了页面输出也希望有导出功能,虽然之前也做过几个导出功能,但这次数据量相对比较大,差不多一天数据就20W条,要求导7天或者30天,那么数据量就轻 ...

  8. Java 创建、填充PDF表单域

    表单域,可以按用途分为多种不同的类型,常见的有文本框.多行文本框.密码框.隐藏域.复选框.单选框和下拉选择框等,目的是用于采集用户的输入或选择的数据.下面的示例中,将分享通过Java编程在PDF中添加 ...

  9. Java实现将Excel导入数据库和从数据库中导出为Excel

    实现的功能: 用Java实现从Excel导入数据库,如果存在就更新 将数据库中的数据导出为Excel 1.添加jxl.jar mysql-connector-java.1.7-bin.jar包到项目的 ...

随机推荐

  1. 9-4 Unidirectional TSP uva116 (DP)

    题意:给一个n行m列矩阵    从第一列任意一个位置出发 每次往右 右上 右下三个方向走一格 直到最后一列   输出所类和的最小值和路径!! 最小值相同则输出字典序最小路径 很像一开始介绍的三角形dp ...

  2. 常用的PHP排序算法以及应用场景

    更多php排序算法应用常景:http://www.bf361.com/algorithm/algorithm-php 1.冒泡排序  冒泡排序:冒泡排序(Bubble Sort),是一种计算机科学领域 ...

  3. java 策略设计模式

    在软件开发中也常常遇到类似的情况,实现某一个功能有多种算法或者策略,我们可以根据环境或者条件的不同选择不同的算法或者策略来完成该功能.如查找.排序等,一种常用的方法是硬编码(Hard Coding)在 ...

  4. 解决命令行运行python文件,出现No module named *** 报错问题

    有时候在一个项目中运行的时候,可能是之前已经mark成sources root 你自己忘记了, 于是就在命令行也执行python文件,然后就出现 No module named *** 等 相关你认为 ...

  5. vue.js 是如何做到数据响应的

    许多前端JavaScript框架(例如Angular,React和Vue)都有自己的数据相应引擎.通过了解相应性及其工作原理,您可以提高开发技能并更有效地使用JavaScript框架.在视频和下面的文 ...

  6. Bipartite Graph hdu 5313 bitset 并查集 二分图

    题目:http://acm.hdu.edu.cn/showproblem.php?pid=5313 题意: 给出n个顶点,m条边,问最多添加多少条边使之构成一个完全二分图 存储结构: bitset   ...

  7. Moo University - Financial Aid POJ 2010 优先队列(最大堆)

    题目:http://poj.org/problem?id=2010 题目大意: 奶牛上大学.因为经济问题,每头奶牛都需要一定的补助需求,学校会提供一定的资金用于补助 每头牛都有自己的分数,学校招收的名 ...

  8. merge into issue

    ORA-30926: unable to get a stable set of rows in the source tables 一.经检查,这个错误是由于数据来源表(即语句中,using后面的f ...

  9. [python 源码]字符串对象的实现

    还是带着问题上路吧,和整数对象的实现同样的问题: >>> a='abc' >>> b='abc' >>> a is b True >> ...

  10. bootbox弹出框插件

    具体用法查看官网http://bootboxjs.com/examples.html {% load staticfiles %} <!DOCTYPE html> <html lan ...