POI 对大数据量的导出是一个难点,这里博主总结了两种处理方式:

方式一,使用高版本的POI,具有内存自动释放的特点。

方式二,将数据导出到多个Excel中,并进行压缩处理,上传到服务器中。

方式一:

POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小效果也不是太好。3.8版本的POI新出来了SXSSFWorkbook,可以支持大数据量的操作,只是SXSSFWorkbook只支持.xlsx格式,不支持.xls格式。

    3.8版本的POI对excel的导出操作,一般只使用HSSFWorkbook以及SXSSFWorkbook,HSSFWorkbook用来处理较少的数据量,SXSSFWorkbook用来处理大数据量以及超大数据量的导出。
   HSSFWorkbook的使用方法和之前的版本的使用方法一致,这里就不在陈述使用方法了
   SXSSFWorkbook的使用例子如下:
import junit.framework.Assert;
import org.apache.poi.ss.usermodel.Cell; 
import org.apache.poi.ss.usermodel.Row; 
import org.apache.poi.ss.usermodel.Sheet; 
import org.apache.poi.ss.usermodel.Workbook; 
import org.apache.poi.ss.util.CellReference; 
import org.apache.poi.xssf.streaming.SXSSFWorkbook;  
public static void main(String[] args) throws Throwable { 
 Workbook wb = new SXSSFWorkbook(100); // keep 100 rows in memory, exceeding rows will be flushed to disk 
 Sheet sh = wb.createSheet(); 
 for(int rownum = 0; rownum < 100000; rownum++){
 Row row = sh.createRow(rownum); 
 for(int cellnum = 0; cellnum < 10; cellnum++){ 
 Cell cell = row.createCell(cellnum); 
 String address = new CellReference(cell).formatAsString(); 
 cell.setCellValue(address); } 
 }
FileOutputStream out = new FileOutputStream("/temp/sxssf.xlsx"); 
 wb.write(out); 
 out.close();
} 
以前还用xml来处理,现在3.8以上就好办了。
原文地址是:http://blog.sina.com.cn/s/blog_68555ee501015xk2.html
apache官网相关内容地址:http://poi.apache.org/spreadsheet/how-to.html#sxssf

方式二:

说明:我的电脑 2.0CPU 2G内存 能够十秒钟导出 20W 条数据 ,12.8M的excel内容压缩后2.68M

我们知道在POI导出Excel时,数据量大了,很容易导致内存溢出。由于Excel 一个sheet允许的最大行数是65536这时我们想到分sheet进行导出;但是这种情况也不能解决内存溢出的问题。毕竟数据还是一次性在内存中进行保存的。这时我们想是不是可以导出多个excel呢?下面我就尝试着按照导出多个excel

首先:我们要确定数据量有多大,然后确定一个excel导出多少条数据,这样就可以确定导出的Excel的数量,于是我们就可以循环的导出excel并保存在任意的临时目录中。去这样如果内存不够的话虚拟机就会去进行回收已经保存的excel在内存中的空间。

假设我们我们已经成功的生成了多个excel,这时我们怎么把这N个excel文档传到客户端呢?其实一个一个的传也未尝不可,但是考虑那样对用户来说体验不够好,再次多个文件在网络上传输也比较慢。我们可以考虑对生成的几个文件进行压缩,然后传到客户端。

总结一下

第一、分批次生成excel

第二、压缩后到客户端

下面我把我的一个小实例贴上供大家参考

第一、Person.java 普通javabean

Javabean代码  
  1. package bean;
  2. /**
  3. *
  4. * @author http://javaflex.iteye.com/
  5. *
  6. */
  7. public class Person {
  8. private Integer id;
  9. private String name;
  10. private String address;
  11. private String tel;
  12. private Double money=0.0;
  13. public Double getMoney() {
  14. return money;
  15. }
  16. public void setMoney(Double money) {
  17. this.money = money;
  18. }
  19. public Person(Integer id, String name, String address, String tel,Double money) {
  20. super();
  21. this.id = id;
  22. this.name = name;
  23. this.address = address;
  24. this.tel = tel;
  25. this.money=money;
  26. }
  27. public Integer getId() {
  28. return id;
  29. }
  30. public void setId(Integer id) {
  31. this.id = id;
  32. }
  33. public String getName() {
  34. return name;
  35. }
  36. public void setName(String name) {
  37. this.name = name;
  38. }
  39. public String getAddress() {
  40. return address;
  41. }
  42. public void setAddress(String address) {
  43. this.address = address;
  44. }
  45. public String getTel() {
  46. return tel;
  47. }
  48. public void setTel(String tel) {
  49. this.tel = tel;
  50. }
  51. }

第二、PersonService模拟业务逻辑循环生成100023个Person对象

模拟业务逻辑代码  
  1. package service;
  2. import java.util.ArrayList;
  3. import java.util.List;
  4. import bean.Person;
  5. /**
  6. *
  7. * @author http://javaflex.iteye.com/
  8. *
  9. */
  10. public class PersonService {
  11. public static List getPerson(){
  12. List<Person> list =new ArrayList<Person>();
  13. for(int i=0;i<100320;i++){
  14. list.add(new Person(i,"zhangsan"+i,"北京"+i,"13214587632",123123.12+i));
  15. }
  16. return list;
  17. }
  18. }

第三、业务处理Servlet

操作servlet代码  
  1. package servlet;
  2. import java.io.File;
  3. import java.io.FileInputStream;
  4. import java.io.FileOutputStream;
  5. import java.io.IOException;
  6. import java.io.OutputStream;
  7. import java.text.SimpleDateFormat;
  8. import java.util.ArrayList;
  9. import java.util.Date;
  10. import java.util.List;
  11. import javax.servlet.ServletException;
  12. import javax.servlet.http.HttpServlet;
  13. import javax.servlet.http.HttpServletRequest;
  14. import javax.servlet.http.HttpServletResponse;
  15. import org.apache.poi.hssf.usermodel.HSSFWorkbook;
  16. import org.apache.poi.hssf.util.CellRangeAddress;
  17. import org.apache.poi.ss.usermodel.Cell;
  18. import org.apache.poi.ss.usermodel.CellStyle;
  19. import org.apache.poi.ss.usermodel.Row;
  20. import org.apache.poi.ss.usermodel.Sheet;
  21. import org.apache.poi.ss.usermodel.Workbook;
  22. import bean.Person;
  23. import service.PersonService;
  24. /**
  25. *
  26. * @author http://javaflex.iteye.com/
  27. *
  28. */
  29. public class PersonServlet extends HttpServlet {
  30. private String fileName;
  31. public PersonServlet() {
  32. super();
  33. }
  34. public void destroy() {
  35. super.destroy(); // Just puts "destroy" string in log
  36. // Put your code here
  37. }
  38. public void doGet(HttpServletRequest request, HttpServletResponse response)
  39. throws ServletException, IOException {
  40. // 文件名获取
  41. Date date = new Date();
  42. SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
  43. String f = "Person-" + format.format(date);
  44. this.fileName = f;
  45. setResponseHeader(response);
  46. OutputStream out = null;
  47. try {
  48. out = response.getOutputStream();
  49. List<Person> list = PersonService.getPerson();
  50. toExcel(list,request,10000,f,out);
  51. } catch (IOException e1) {
  52. e1.printStackTrace();
  53. } finally {
  54. try {
  55. out.flush();
  56. out.close();
  57. } catch (IOException e) {
  58. e.printStackTrace();
  59. }
  60. }
  61. }
  62. /** 设置响应头 */
  63. public void setResponseHeader(HttpServletResponse response) {
  64. try {
  65. response.setContentType("application/octet-stream;charset=UTF-8");
  66. response.setHeader("Content-Disposition", "attachment;filename="
  67. + java.net.URLEncoder.encode(this.fileName, "UTF-8")
  68. + ".zip");
  69. response.addHeader("Pargam", "no-cache");
  70. response.addHeader("Cache-Control", "no-cache");
  71. } catch (Exception ex) {
  72. ex.printStackTrace();
  73. }
  74. }
  75. public void doPost(HttpServletRequest request, HttpServletResponse response)
  76. throws ServletException, IOException {
  77. doGet(request, response);
  78. }
  79. public void init() throws ServletException {
  80. // Put your code here
  81. }
  82. public void toExcel(List<Person> list, HttpServletRequest request,
  83. int length, String f, OutputStream out) throws IOException {
  84. List<String> fileNames = new ArrayList();// 用于存放生成的文件名称s
  85. File zip = new File(request.getRealPath("/files") + "/" + f + ".zip");// 压缩文件
  86. // 生成excel
  87. for (int j = 0, n = list.size() / length + 1; j < n; j++) {
  88. Workbook book = new HSSFWorkbook();
  89. Sheet sheet = book.createSheet("person");
  90. double d = 0;// 用来统计
  91. String file = request.getRealPath("/files") + "/" + f + "-" + j
  92. + ".xls";
  93. fileNames.add(file);
  94. FileOutputStream o = null;
  95. try {
  96. o = new FileOutputStream(file);
  97. // sheet.addMergedRegion(new
  98. // CellRangeAddress(list.size()+1,0,list.size()+5,6));
  99. Row row = sheet.createRow(0);
  100. row.createCell(0).setCellValue("ID");
  101. row.createCell(1).setCellValue("NAME");
  102. row.createCell(2).setCellValue("ADDRESS");
  103. row.createCell(3).setCellValue("TEL");
  104. row.createCell(4).setCellValue("Money");
  105. int m = 1;
  106. for (int i = 1, min = (list.size() - j * length + 1) > (length + 1) ? (length + 1)
  107. : (list.size() - j * length + 1); i < min; i++) {
  108. m++;
  109. Person user = list.get(length * (j) + i - 1);
  110. Double dd = user.getMoney();
  111. if (dd == null) {
  112. dd = 0.0;
  113. }
  114. d += dd;
  115. row = sheet.createRow(i);
  116. row.createCell(0).setCellValue(user.getId());
  117. row.createCell(1).setCellValue(user.getName());
  118. row.createCell(2).setCellValue(user.getAddress());
  119. row.createCell(3).setCellValue(user.getTel());
  120. row.createCell(4).setCellValue(dd);
  121. }
  122. CellStyle cellStyle2 = book.createCellStyle();
  123. cellStyle2.setAlignment(CellStyle.ALIGN_CENTER);
  124. row = sheet.createRow(m);
  125. Cell cell0 = row.createCell(0);
  126. cell0.setCellValue("Total");
  127. cell0.setCellStyle(cellStyle2);
  128. Cell cell4 = row.createCell(4);
  129. cell4.setCellValue(d);
  130. cell4.setCellStyle(cellStyle2);
  131. sheet.addMergedRegion(new CellRangeAddress(m, m, 0, 3));
  132. } catch (Exception e) {
  133. e.printStackTrace();
  134. }
  135. try {
  136. book.write(o);
  137. } catch (Exception ex) {
  138. ex.printStackTrace();
  139. } finally {
  140. o.flush();
  141. o.close();
  142. }
  143. }
  144. File srcfile[] = new File[fileNames.size()];
  145. for (int i = 0, n = fileNames.size(); i < n; i++) {
  146. srcfile[i] = new File(fileNames.get(i));
  147. }
  148. util.FileZip.ZipFiles(srcfile, zip);
  149. FileInputStream inStream = new FileInputStream(zip);
  150. byte[] buf = new byte[4096];
  151. int readLength;
  152. while (((readLength = inStream.read(buf)) != -1)) {
  153. out.write(buf, 0, readLength);
  154. }
  155. inStream.close();
  156. }
  157. }

最后还有个工具类package util;

压缩工具类代码  
  1. import java.io.FileInputStream;
  2. import java.io.FileOutputStream;
  3. import java.io.IOException;
  4. import java.util.zip.ZipEntry;
  5. import java.util.zip.ZipOutputStream;
  6. /**
  7. *
  8. * @author http://javaflex.iteye.com/
  9. *
  10. */
  11. public class FileZip {
  12. /**
  13. *
  14. * @param srcfile 文件名数组
  15. * @param zipfile 压缩后文件
  16. */
  17. public static void ZipFiles(java.io.File[] srcfile, java.io.File zipfile) {
  18. byte[] buf = new byte[1024];
  19. try {
  20. ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
  21. zipfile));
  22. for (int i = 0; i < srcfile.length; i++) {
  23. FileInputStream in = new FileInputStream(srcfile[i]);
  24. out.putNextEntry(new ZipEntry(srcfile[i].getName()));
  25. int len;
  26. while ((len = in.read(buf)) > 0) {
  27. out.write(buf, 0, len);
  28. }
  29. out.closeEntry();
  30. in.close();
  31. }
  32. out.close();
  33. } catch (IOException e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. }

OK全部内容完成

12.8M的excel内容压缩后2.68M,给力吧

以后记得代码加注释

亲,记得给个评论哦

  • 大小: 4.4 KB
  • 大小: 2.5 KB
  • POI.rar (5.7 MB)
  • 下载次数: 1449

JavaWEB_POI导出大量数据excel(50万左右)相关推荐

  1. jconsole 查看 SXSSFWorkbook导出百万数据excel内存使用情况

    模拟代码如下:计划使用SXSSFworkbook导出1000000行,230列数据的excel. import org.apache.poi.xssf.streaming.SXSSFCell; imp ...

  2. 导出超大数据excel,基于EEC实现

    简要说明: 大数据导出导入excel,网上许多使用EasyExcel进行实现,但EasyExcel是基于Apache poi进行封装的所以存在一个共病[占用内存过大],在找了许多个poi框架如Auto ...

  3. POI3.8 导出大数据excel(50万左右)

    转载地址http://blog.csdn.net/yys79/article/details/26443603 POI之前的版本不支持大数据量处理,如果数据过多则经常报OOM错误,有时候调整JVM大小 ...

  4. JAVA 导出大批量数据EXCEL

    转自http://www.itboth.com/d/MjI3Ef/excel-java 参考资料:http://bbs.51cto.com/thread-1074293-1-1.html http:/ ...

  5. POI导出百万数据 EXCEL addMergedReigon 合并单元格慢的问题解决

    本文最重要的就是以下重写的方法,如果你仅仅是感觉导出慢,原因又是因为合并单元格,那么你直接用一下方法合并就好. private static void addMergedReigon(CTWorksh ...

  6. 使用Mysql Navcat导出查询数据excel时出现数据丢失

    背景 今天应产品运营的需要,需要导出一批订单数据,总数一共是七万多.按照以往的方式使用navicat将查询出来的表结果以excel的形式导出. 导出至本地打开excel后发现算上表头一共才65536行 ...

  7. PHPExcel 导出的数据Excel打开出现 部分内容有问题是否让我们尽量尝试恢复的问题解决方案

    PHPExcel 导出之后WPS打开正常,Excel错误解决方案具体如下 在我们导出数据到本地的时候用Excel打开发现会出现以下弹窗: 而用金山的WPS却没有问题.下面看一下解决方案. 其实很简单, ...

  8. java导出大数据excel表格,导出数据

    常规的java导出excel表格最大的数据量是65535行. package com.sf.module.timeManagement.biz; import java.io.ByteArrayInp ...

  9. layui实现导出全部数据Excel

    因为layui官网实现的是导出当前页的数据(20190718),所以下面的代码是实现导出全部的数据和选择性数据导出. 大家可以搜索标题下载选择性导出数据.使用的框架:spring,springmvc, ...

最新文章

  1. Python 生成器总结
  2. 首次成功实施 XSS 攻击,盗取目标网站大量 VIP 帐号
  3. asp.net 检测是否关注公众号_太阳电池缺陷检测方法光致发光检测法
  4. LeetCode 105 Construct Binary Tree from Preorder and Inorder Traversal-前序中序遍历构造二叉树-Python和Java递归解法
  5. MySQL 事务到底是隔离还是不隔离?
  6. 金蝶K3,如何添加其它出库单出库类型
  7. 合成模式(Composite Pattern)
  8. 【Linux】一步一步学Linux——gcc命令(249)
  9. 导入要素集到SDE数据库的方法以及使用GP工具的许可问题(转载)
  10. C语言和JAVA可以互相转换吗,求助大神!!!JAVA转换成C语言
  11. 【必懂C++】第一个程序当然是HelloWorld呀 01
  12. Python使用matplotlib填充图形指定区域
  13. 用户增长:APP推广的五大方法
  14. 学计算机怎能不知道电脑配置
  15. D3D9利用顶点缓冲区绘制三角形
  16. 负反馈元器件参数对功放性能的影响
  17. 再度递表港交所,“快”能否成为绿茶餐厅突围的筹码?
  18. android逆向分析腾讯微视研究无限循环视频嵌套滑动不中断的实现方式
  19. curl 实现qq挂号登录
  20. 浙江大华前端一二三面经(2021届校招)

热门文章

  1. jgit比较项目不同版本间的差异及统计代码总行数
  2. kafka send failed: dial tcp: lookup hostname: no such host
  3. 设计一款CPU到底有多难?
  4. 校招面试——Java 基础知识
  5. 判断网络是否使用代理服务器
  6. [2017全球人工智能高峰论坛]城市大脑是下一个十年的登月计划 王坚说出了什么?...
  7. sprintboot 微信静默授权代码
  8. 1000瓶无色无味的药水,其中有一瓶毒药,10只小白鼠拿过来做实验
  9. JS之setInterval方法
  10. 汇编中各寄存器的作用(16位CPU14个,32位CPU16个)和 x86汇编指令集大全(带注释)...