POI导出大量数据的简单解决方案

转载自:http://bbs.chinaunix.net/thread-3620272-1-1.html

说明:我的电脑 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 QQ:三二8二4七6七六  
  5. *  
  6. */  
  7. public class Person {  
  8.   
  9.     private Integer id;  
  10.     private String name;  
  11.     private String address;  
  12.     private String tel;  
  13.     private Double money=0.0;  
  14.     public Double getMoney() {  
  15.         return money;  
  16.     }  
  17.     public void setMoney(Double money) {  
  18.         this.money = money;  
  19.     }  
  20.     public Person(Integer id, String name, String address, String tel,Double money) {  
  21.         super();  
  22.         this.id = id;  
  23.         this.name = name;  
  24.         this.address = address;  
  25.         this.tel = tel;  
  26.         this.money=money;  
  27.     }  
  28.     public Integer getId() {  
  29.         return id;  
  30.     }  
  31.     public void setId(Integer id) {  
  32.         this.id = id;  
  33.     }  
  34.     public String getName() {  
  35.         return name;  
  36.     }  
  37.     public void setName(String name) {  
  38.         this.name = name;  
  39.     }  
  40.     public String getAddress() {  
  41.         return address;  
  42.     }  
  43.     public void setAddress(String address) {  
  44.         this.address = address;  
  45.     }  
  46.     public String getTel() {  
  47.         return tel;  
  48.     }  
  49.     public void setTel(String tel) {  
  50.         this.tel = tel;  
  51.     }  
  52. }  
复制代码
第二、PersonService模拟业务逻辑循环生成100023个Person对象

模拟业务逻辑代码
  1. package service;  
  2.   
  3. import java.util.ArrayList;  
  4. import java.util.List;  
  5.   
  6. import bean.Person;  
  7. /**  
  8. *   
  9. * @author QQ:三二8二4七6七六  
  10. *  
  11. */  
  12. public class PersonService {  
  13.     public static List getPerson(){  
  14.         List<Person> list =new ArrayList<Person>();  
  15.         for(int i=0;i<100320;i++){  
  16.             list.add(new Person(i,"zhangsan"+i,"北京"+i,"13214587632",123123.12+i));   
  17.         }  
  18.         return list;  
  19.     }  
  20.   
  21. }  
复制代码
第三、业务处理Servlet

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

发布了17 篇原创文章 · 获赞 24 · 访问量 12万+
展开阅读全文

小白求助:poi生成excel速度过慢问题,该怎么优化

01-20

package poiMain; import java.io.FileInputStream; import java.io.FileOutputStream; import java.io.IOException; import java.io.InputStream; import java.text.DateFormat; import java.text.DecimalFormat; import java.text.SimpleDateFormat; import java.util.ArrayList; import java.util.Date; import java.util.Scanner; import org.apache.poi.hssf.usermodel.HSSFCell; import org.apache.poi.hssf.usermodel.HSSFCellStyle; import org.apache.poi.hssf.usermodel.HSSFDataFormat; import org.apache.poi.hssf.usermodel.HSSFDateUtil; import org.apache.poi.ss.usermodel.Font; import org.apache.poi.xssf.usermodel.XSSFCell; import org.apache.poi.xssf.usermodel.XSSFCellStyle; import org.apache.poi.xssf.usermodel.XSSFFont; import org.apache.poi.xssf.usermodel.XSSFRow; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class PoiGH3215 { private static String fileName=""; public static String getCell(int x,int y) throws IOException{ DecimalFormat df = new DecimalFormat("#"); InputStream myxls=new FileInputStream(fileName); @SuppressWarnings("resource") XSSFWorkbook wb =new XSSFWorkbook(myxls); XSSFSheet sheet=wb.getSheetAt(0);//第一个工作表 XSSFRow row =sheet.getRow(x-1);//第x行 XSSFCell cell =row.getCell((short)y-1);//第x行第y个元素 if(cell==null){ return null; } String cellValue = ""; switch (cell.getCellType()) { case HSSFCell.CELL_TYPE_STRING: cellValue = cell.getRichStringCellValue().getString().trim(); break; case HSSFCell.CELL_TYPE_NUMERIC: if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式 SimpleDateFormat sdf = null; if (cell.getCellStyle().getDataFormat() == HSSFDataFormat .getBuiltinFormat("h:mm")) { sdf = new SimpleDateFormat("HH:mm"); } else {// 日期 sdf = new SimpleDateFormat("yyyy/MM/dd"); } Date date = cell.getDateCellValue(); cellValue = sdf.format(date); } else { cellValue = df.format(cell.getNumericCellValue()).toString(); } break; default: cellValue = ""; } return cellValue; } public static void ModelGH3215() throws IOException{ @SuppressWarnings("resource") XSSFWorkbook wb =new XSSFWorkbook(); Date d = new Date(); DateFormat df = new SimpleDateFormat("yyyyMMddHHmmss"); String fileName = df.format(d); FileOutputStream fileOut = new FileOutputStream("D:/输出/工行3215/" + fileName + "_main" + ".xls"); XSSFSheet sheet=wb.createSheet(); Font font = wb.createFont(); XSSFCellStyle style = wb.createCellStyle(); //新建单元格样式 font.setFontName("宋体"); font.setFontHeightInPoints((short) 12);//设置字体大小 font.setBoldweight(XSSFFont.BOLDWEIGHT_BOLD);//粗体显示 style.setAlignment(HSSFCellStyle.ALIGN_CENTER);//居中 style.setVerticalAlignment(HSSFCellStyle.VERTICAL_CENTER);//垂直 style.setBorderBottom(HSSFCellStyle.BORDER_MEDIUM); //下边框 style.setFont(font); //设置单元格列宽 sheet.setColumnWidth(0, 100 * 100); sheet.setColumnWidth(1, 100 * 30); sheet.setColumnWidth(3, 100 * 30); sheet.setColumnWidth(4, 100 * 30); sheet.setColumnWidth(9, 100 * 130); sheet.setColumnWidth(20, 100 * 40); XSSFRow row =sheet.createRow((short)0); XSSFCell cell=row.createCell((short)0); row.setHeight((short) 700);//设置行高 cell.setCellValue("银行科目"); row.getCell((short)0).setCellStyle(style); row.createCell((short)1).setCellValue("币别"); row.getCell((short)1).setCellStyle(style); row.createCell((short)2).setCellValue("序列号"); row.getCell((short)2).setCellStyle(style); row.createCell((short)3).setCellValue("日期"); row.getCell((short)3).setCellStyle(style); row.createCell((short)4).setCellValue("业务日期"); row.getCell((short)4).setCellStyle(style); row.createCell((short)5).setCellValue("凭证字"); row.getCell((short)5).setCellStyle(style); row.createCell((short)6).setCellValue("凭证号"); row.getCell((short)6).setCellStyle(style); row.createCell((short)7).setCellValue("凭证年"); row.getCell((short)7).setCellStyle(style); row.createCell((short)8).setCellValue("凭证期间"); row.getCell((short)8).setCellStyle(style); row.createCell((short)9).setCellValue("摘要"); row.getCell((short)9).setCellStyle(style); row.createCell((short)10).setCellValue("对方科目"); row.getCell((short)10).setCellStyle(style); row.createCell((short)11).setCellValue("结算方式"); row.getCell((short)11).setCellStyle(style); row.createCell((short)12).setCellValue("结算号"); row.getCell((short)12).setCellStyle(style); row.createCell((short)13).setCellValue(""); row.getCell((short)13).setCellStyle(style); row.createCell((short)14).setCellValue(""); row.getCell((short)14).setCellStyle(style); row.createCell((short)15).setCellValue("汇率"); row.getCell((short)15).setCellStyle(style); row.createCell((short)16).setCellValue("附件数"); row.getCell((short)16).setCellStyle(style); row.createCell((short)17).setCellValue("汇率类型"); row.getCell((short)17).setCellStyle(style); row.createCell((short)18).setCellValue("备注"); row.getCell((short)18).setCellStyle(style); row.createCell((short)19).setCellValue("对应外币"); row.getCell((short)19).setCellStyle(style); row.createCell((short)20).setCellValue("对应外币金额"); row.getCell((short)20).setCellStyle(style); int j = 1;int sum=0;int a=0;int s=getNum(); ArrayList<String> date1 = new ArrayList(); ArrayList<Integer> value1 = new ArrayList(); ArrayList<String> date2 = new ArrayList(); ArrayList<Integer> value2 = new ArrayList(); for(int i=5;i<s+2;i++){ if(PoiGH3215.getCell(i,4).equals("转款")&&(PoiGH3215.getCell(i,8).equals("31001547840050012398"))){ System.out.println("get"); XSSFRow row2 =sheet.createRow((short)j++); row2.createCell((short)14).setCellValue(getCell(i,5)); row2.createCell((short)13).setCellValue(getCell(i,7)); row2.createCell((short)3).setCellValue(getCell(i,2));//日期 row2.createCell((short)4).setCellValue(getCell(i,2));//日期 row2.createCell((short)0).setCellValue("1021.01.10|工行广州白云路支行(8980)-备汇缴");//第一列 row2.createCell((short)9).setCellValue("收转款,建行怒江2398转入工行侨香");//摘要 }else if(PoiGH3215.getCell(i,4).equals("收付")&&(!PoiGH3215.getCell(i,5).equals(PoiGH3215.getCell(i,6)))){ XSSFRow row3 =sheet.createRow((short)j); row3.createCell((short)9).setCellValue("付移动手机充值款"); row3.createCell((short)13).setCellValue(getCell(i,7));//添加值 row3.createCell((short)14).setCellValue(getCell(i,5));//添加值 row3.createCell((short)3).setCellValue(getCell(j,2)); row3.createCell((short)4).setCellValue(getCell(j,2)); row3.createCell((short)0).setCellValue("1021.01.10|工行广州白云路支行(8980)-备汇缴"); row3.createCell((short)14).setCellValue(getCell(i,5)); row3.createCell((short)9).setCellValue("收还款退款");//摘要 } else if(PoiGH3215.getCell(i,4).equals("收付")&&(PoiGH3215.getCell(i,5).equals(PoiGH3215.getCell(i,6)))){ XSSFRow row3 =sheet.createRow((short)j); row3.createCell((short)9).setCellValue("付移动手机充值款"); row3.createCell((short)13).setCellValue(getCell(i,7)); row3.createCell((short)14).setCellValue(getCell(i,5));//添加值 row3.createCell((short)3).setCellValue(getCell(j,2)); row3.createCell((short)4).setCellValue(getCell(j,2)); row3.createCell((short)0).setCellValue("1021.01.10|工行广州白云路支行(8980)-备汇缴"); row3.createCell((short)14).setCellValue(getCell(i,5)); row3.createCell((short)9).setCellValue("收收付");//摘要 } else if(PoiGH3215.getCell(i,4).equals("拉卡拉代付款")&&(!PoiGH3215.getCell(i,9).equals("拉卡拉支付有限公司客户备付金"))&&(!PoiGH3215.getCell(i,9).equals("拉卡拉支付有限公司(客户备付金)"))&&(!PoiGH3215.getCell(i,9).equals("拉卡拉网络技术有限公司北京分公司的数(合计数)"))){ //System.out.println(i); date1.add(PoiGH3215.getCell(i,2)); value1.add(Integer.parseInt(PoiGH3215.getCell(i,5))); } } for(int c=0;c<date1.size();c++){ try { if(date1.get(c).equals(date1.get(c+1))){ a=value1.get(c); sum=a+sum; }else { a= value1.get(c); sum=a+sum; date2.add(date1.get(c)); value2.add(sum); sum=0; } } catch (Exception e) { a=value1.get(c); sum=a+sum; date2.add(date1.get(c)); value2.add(sum); } } for(int k=0;k<date2.size();k++){ XSSFRow row3 =sheet.createRow((short)j+k); row3.createCell((short)14).setCellValue(value2.get(k)); row3.createCell((short)9).setCellValue("付代付款"); row3.createCell((short)3).setCellValue(date2.get(k)); row3.createCell((short)4).setCellValue(date2.get(k)); row3.createCell((short)0).setCellValue("1021.01.10|工行广州白云路支行(8980)-备汇缴"); } for(int m=1;m<j+date2.size();m++){ XSSFRow row2 =sheet.getRow((short)m); row2.createCell((short)1).setCellValue("RMB|人民币"); row2.createCell((short)15).setCellValue("1"); row2.createCell((short)16).setCellValue("0"); row2.createCell((short)17).setCellValue("01|公司汇率"); row2.createCell((short)20).setCellValue("0"); } wb.write(fileOut); fileOut.close(); System.out.println("输入完毕"); } public static int getNum() throws IOException{ synchronized (fileName) { while("".equals(fileName)){ System.out.println("请输入您的文件路径:"); Scanner sc = new Scanner(System.in); fileName = sc.nextLine(); sc.close(); } } InputStream myxls=new FileInputStream(fileName); @SuppressWarnings("resource") XSSFWorkbook wb =new XSSFWorkbook(myxls); XSSFSheet sheet=wb.getSheetAt(0);//第一个工作表 return sheet.getLastRowNum(); } } 我要处理的表有6万多行,我这个处理一个200行的都要1分钟 问答

没有更多推荐了,返回首页

©️2019 CSDN 皮肤主题: 大白 设计师: CSDN官方博客

分享到微信朋友圈

×

扫一扫,手机浏览