POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)
说明:我的电脑 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
- package bean;
- /**
- *
- * @author http://javaflex.iteye.com/
- *
- */
- public class Person {
- private Integer id;
- private String name;
- private String address;
- private String tel;
- private Double money=0.0;
- public Double getMoney() {
- return money;
- }
- public void setMoney(Double money) {
- this.money = money;
- }
- public Person(Integer id, String name, String address, String tel,Double money) {
- super();
- this.id = id;
- this.name = name;
- this.address = address;
- this.tel = tel;
- this.money=money;
- }
- public Integer getId() {
- return id;
- }
- public void setId(Integer id) {
- this.id = id;
- }
- public String getName() {
- return name;
- }
- public void setName(String name) {
- this.name = name;
- }
- public String getAddress() {
- return address;
- }
- public void setAddress(String address) {
- this.address = address;
- }
- public String getTel() {
- return tel;
- }
- public void setTel(String tel) {
- this.tel = tel;
- }
- }
第二、PersonService模拟业务逻辑循环生成100023个Person对象
- package service;
- import java.util.ArrayList;
- import java.util.List;
- import bean.Person;
- /**
- *
- * @author http://javaflex.iteye.com/
- *
- */
- public class PersonService {
- public static List getPerson(){
- List<Person> list =new ArrayList<Person>();
- for(int i=0;i<100320;i++){
- list.add(new Person(i,"zhangsan"+i,"北京"+i,"13214587632",123123.12+i));
- }
- return list;
- }
- }
第三、业务处理Servlet
- package servlet;
- import java.io.File;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.io.OutputStream;
- import java.text.SimpleDateFormat;
- import java.util.ArrayList;
- import java.util.Date;
- import java.util.List;
- import javax.servlet.ServletException;
- import javax.servlet.http.HttpServlet;
- import javax.servlet.http.HttpServletRequest;
- import javax.servlet.http.HttpServletResponse;
- import org.apache.poi.hssf.usermodel.HSSFWorkbook;
- import org.apache.poi.hssf.util.CellRangeAddress;
- import org.apache.poi.ss.usermodel.Cell;
- import org.apache.poi.ss.usermodel.CellStyle;
- import org.apache.poi.ss.usermodel.Row;
- import org.apache.poi.ss.usermodel.Sheet;
- import org.apache.poi.ss.usermodel.Workbook;
- import bean.Person;
- import service.PersonService;
- /**
- *
- * @author http://javaflex.iteye.com/
- *
- */
- public class PersonServlet extends HttpServlet {
- private String fileName;
- public PersonServlet() {
- super();
- }
- public void destroy() {
- super.destroy(); // Just puts "destroy" string in log
- // Put your code here
- }
- public void doGet(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- // 文件名获取
- Date date = new Date();
- SimpleDateFormat format = new SimpleDateFormat("yyyyMMddHHmmss");
- String f = "Person-" + format.format(date);
- this.fileName = f;
- setResponseHeader(response);
- OutputStream out = null;
- try {
- out = response.getOutputStream();
- List<Person> list = PersonService.getPerson();
- toExcel(list,request,10000,f,out);
- } catch (IOException e1) {
- e1.printStackTrace();
- } finally {
- try {
- out.flush();
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
- /** 设置响应头 */
- public void setResponseHeader(HttpServletResponse response) {
- try {
- response.setContentType("application/octet-stream;charset=UTF-8");
- response.setHeader("Content-Disposition", "attachment;filename="
- + java.net.URLEncoder.encode(this.fileName, "UTF-8")
- + ".zip");
- response.addHeader("Pargam", "no-cache");
- response.addHeader("Cache-Control", "no-cache");
- } catch (Exception ex) {
- ex.printStackTrace();
- }
- }
- public void doPost(HttpServletRequest request, HttpServletResponse response)
- throws ServletException, IOException {
- doGet(request, response);
- }
- public void init() throws ServletException {
- // Put your code here
- }
- public void toExcel(List<Person> list, HttpServletRequest request,
- int length, String f, OutputStream out) throws IOException {
- List<String> fileNames = new ArrayList();// 用于存放生成的文件名称s
- File zip = new File(request.getRealPath("/files") + "/" + f + ".zip");// 压缩文件
- // 生成excel
- for (int j = 0, n = list.size() / length + 1; j < n; j++) {
- Workbook book = new HSSFWorkbook();
- Sheet sheet = book.createSheet("person");
- double d = 0;// 用来统计
- String file = request.getRealPath("/files") + "/" + f + "-" + j
- + ".xls";
- fileNames.add(file);
- FileOutputStream o = null;
- try {
- o = new FileOutputStream(file);
- // sheet.addMergedRegion(new
- // CellRangeAddress(list.size()+1,0,list.size()+5,6));
- Row row = sheet.createRow(0);
- row.createCell(0).setCellValue("ID");
- row.createCell(1).setCellValue("NAME");
- row.createCell(2).setCellValue("ADDRESS");
- row.createCell(3).setCellValue("TEL");
- row.createCell(4).setCellValue("Money");
- int m = 1;
- for (int i = 1, min = (list.size() - j * length + 1) > (length + 1) ? (length + 1)
- : (list.size() - j * length + 1); i < min; i++) {
- m++;
- Person user = list.get(length * (j) + i - 1);
- Double dd = user.getMoney();
- if (dd == null) {
- dd = 0.0;
- }
- d += dd;
- row = sheet.createRow(i);
- row.createCell(0).setCellValue(user.getId());
- row.createCell(1).setCellValue(user.getName());
- row.createCell(2).setCellValue(user.getAddress());
- row.createCell(3).setCellValue(user.getTel());
- row.createCell(4).setCellValue(dd);
- }
- CellStyle cellStyle2 = book.createCellStyle();
- cellStyle2.setAlignment(CellStyle.ALIGN_CENTER);
- row = sheet.createRow(m);
- Cell cell0 = row.createCell(0);
- cell0.setCellValue("Total");
- cell0.setCellStyle(cellStyle2);
- Cell cell4 = row.createCell(4);
- cell4.setCellValue(d);
- cell4.setCellStyle(cellStyle2);
- sheet.addMergedRegion(new CellRangeAddress(m, m, 0, 3));
- } catch (Exception e) {
- e.printStackTrace();
- }
- try {
- book.write(o);
- } catch (Exception ex) {
- ex.printStackTrace();
- } finally {
- o.flush();
- o.close();
- }
- }
- File srcfile[] = new File[fileNames.size()];
- for (int i = 0, n = fileNames.size(); i < n; i++) {
- srcfile[i] = new File(fileNames.get(i));
- }
- util.FileZip.ZipFiles(srcfile, zip);
- FileInputStream inStream = new FileInputStream(zip);
- byte[] buf = new byte[4096];
- int readLength;
- while (((readLength = inStream.read(buf)) != -1)) {
- out.write(buf, 0, readLength);
- }
- inStream.close();
- }
- }
最后还有个工具类package util;
- import java.io.FileInputStream;
- import java.io.FileOutputStream;
- import java.io.IOException;
- import java.util.zip.ZipEntry;
- import java.util.zip.ZipOutputStream;
- /**
- *
- * @author http://javaflex.iteye.com/
- *
- */
- public class FileZip {
- /**
- *
- * @param srcfile 文件名数组
- * @param zipfile 压缩后文件
- */
- public static void ZipFiles(java.io.File[] srcfile, java.io.File zipfile) {
- byte[] buf = new byte[1024];
- try {
- ZipOutputStream out = new ZipOutputStream(new FileOutputStream(
- zipfile));
- for (int i = 0; i < srcfile.length; i++) {
- FileInputStream in = new FileInputStream(srcfile[i]);
- out.putNextEntry(new ZipEntry(srcfile[i].getName()));
- int len;
- while ((len = in.read(buf)) > 0) {
- out.write(buf, 0, len);
- }
- out.closeEntry();
- in.close();
- }
- out.close();
- } catch (IOException e) {
- e.printStackTrace();
- }
- }
- }
OK全部内容完成
12.8M的excel内容压缩后2.68M,给力吧
以后记得代码加注释
亲,记得给个评论哦
源码下载地址:http://dl.iteye.com/topics/download/87b5eb63-e4d2-345f-937c-802b88af8432
文章来自:http://javaflex.iteye.com/blog/1264127
POI导出大量数据的简单解决方案(附源码)-Java-POI导出大量数据,导出Excel文件,压缩ZIP(转载自iteye.com)的更多相关文章
- 3.NetDh框架之缓存操作类和二次开发模式简单设计(附源码和示例代码)
前言 NetDh框架适用于C/S.B/S的服务端框架,可用于项目开发和学习.目前包含以下四个模块 1.数据库操作层封装Dapper,支持多种数据库类型.多库实例,简单强大: 此部分具体说明可参考博客: ...
- Python爬取某网站文档数据完整教程(附源码)
基本开发环境 (https://jq.qq.com/?_wv=1027&k=NofUEYzs) Python 3.6 Pycharm 相关模块的使用 (https://jq.qq.com/?_ ...
- 高性能页面加载技术(流水线加载)BigPipe的C#简单实现(附源码)
一,BigPipe简介 BigPipe是一个重新设计的基础动态网页服务体系.大体思路是,分解网页成叫做Pagelets的小块,然后通过Web服务器和浏览器建立管道并管理他们在不同阶段的运行.这是类似于 ...
- AJAX技术之网易滚动新闻的简单实现(附源码)--AJAX
1.AJAX简介: AJAX = Asynchronous JavaScript and XML(异步的 JavaScript 和 XML). AJAX 不是新的编程语言,而是一种使用现有标准的新方法 ...
- 使用JDBC技术连接数据库(附源码)--JAVA的简单应用
一.创建数据库(以mysql数据库为例) mysql数据库的下载安装与配置 -可参考博主之前的随笔:Windows平台下搭建MySQL数据库 创建wxb数据库-create database wxb; ...
- leaflet 结合 d3.js 实现 geojson 数据地形剖面分析(附源码下载)
前言 leaflet 入门开发系列环境知识点了解: leaflet api文档介绍,详细介绍 leaflet 每个类的函数以及属性等等 leaflet 在线例子 leaflet 插件,leaflet ...
- PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二手急速响应捡垃圾平台_3(附源码持续更新)
说明 文章首发于HURUWO的博客小站,本平台做同步备份发布. 如有浏览或访问异常图片加载失败或者相关疑问可前往原博客下评论浏览. 原文链接 PYTHON爬虫实战_垃圾佬闲鱼爬虫转转爬虫数据整合自用二 ...
- 极限挑战—C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码)
原文:极限挑战-C#100万条数据导入SQL SERVER数据库仅用4秒 (附源码) 实际工作中有时候需要把大量数据导入数据库,然后用于各种程序计算,本实验将使用5中方法完成这个过程,并详细记录各种方 ...
- PHP简单的长文章分页教程 附源码
PHP简单的长文章分页教程 附源码.本文将content.txt里的内容分割成3页,这样浏览起来用户体验很好. 根据分页参数ipage,获取对应文章内容 include('page.class.php ...
随机推荐
- Windows Server 2012启用Windows功能NetFx3时出错解决方法
作者:冰点阳光 | 可以转载, 但必须以超链接形式标明文章原始出处和作者信息及版权声明网址:http://baohua.me/operating-system/windows-server-2012- ...
- poj 1975 Median Weight Bead(传递闭包 Floyd)
链接:poj 1975 题意:n个珠子,给定它们之间的重量关系.按重量排序.求确定肯定不排在中间的珠子的个数 分析:由于n为奇数.中间为(n+1)/2,对于某个珠子.若有至少有(n+1)/2个珠子比它 ...
- curl 要么 file_get_contents 获得授权页面的方法的必要性
今天,需要工作,需要使用 curl / file_get_contents 获得授权的必要性(Authorization)的页面内容.解决后写了这篇文章分享给大家. php curl 扩展,可以在se ...
- SQL Server 2008 R2 性能计数器详细列表(四)
原文:SQL Server 2008 R2 性能计数器详细列表(四) SQL Server Latches 对象: 监视称为闩锁的内部 SQL Server 资源锁.通过监视闩锁来确定用户活动和资源使 ...
- 使用Inno Setup 打包jdk、mysql、tomcat、webapp等为一个exe安装包(转)
之前一直都没涉及到打包安装方面的东西,都是另一个同事负责的,使用的工具(installshield)也比较高大上一点,可是后来他离职以后接受的同事也只能是在这个基础上做个简单的配置,然后打包,可是现在 ...
- .NET(C#):浅谈程序集清单资源和RESX资源
原文:.NET(C#):浅谈程序集清单资源和RESX资源 目录 程序集清单资源 RESX资源文件 使用ResourceReader和ResourceSet解析二进制资源文件 使用ResourceM ...
- 皴linux rootpassword(方式:重置rootpassword)
皴linux rootpassword: 开机后,.点击"e"进入维护模式.选"内核选项",例如,看到下面的数字: watermark/2/text/aHR0c ...
- Unix / 类 Unix shell 中有哪些很酷很冷门很少用很有用的命令?(转)
著作权归作者所有. 商业转载请联系作者获得授权,非商业转载请注明出处. 作者:孙立伟 链接:http://www.zhihu.com/question/20140085/answer/14107336 ...
- Linux:闪光的宝石,智慧(下一个)
2005年4月7日.Linus Torvalds公布了一款新型通用工具软件包,叫做"Git"(the Git source code management system).&quo ...
- char* 和char[]差异
从因特网以下内容.笔者和总结汇总. 1. 问题介绍 问题引入: 在实习过程中发现了一个曾经一直默认的错误.相同char *c = "abc"和char c[]="abc& ...