java导出大批量(百万以上)数据的excel文件

1.传统的导出方式会消耗大量的内存,2003每个sheet页最多65536条数据,2007每个sheet页可以达到100万条数据以上,2007会在生成Workbook时清理数据,所以2007导出量更大;

2.可以导出多个excel文件到某个目录中,然后打包下载;

3.导出excel格式的xml文件,这种方式可以分批导出数据,适用于大批量数据的导出,以下简单介绍这种方式:

代码如下:

  1 package com.epay.utils;
  2 
  3 /**
  4  * 大数据量导出成EXCEL或XML
  5  * @author qad
  6  * 2017-04-22
  7  */
  8 import java.io.BufferedOutputStream;
  9 import java.io.DataOutputStream;
 10 import java.io.File;
 11 import java.io.FileNotFoundException;
 12 import java.io.FileOutputStream;
 13 import java.io.IOException;
 14 
 15 public class Test {
 16     public static void main(String[] args) {
 17         StringBuffer sb = new StringBuffer();
 18         try {
 19             DataOutputStream rafs = new DataOutputStream(
 20                     new BufferedOutputStream(new FileOutputStream(new File(
 21                             "d://test.xls"))));
 22             sb.append("<?xml version=\"1.0\" encoding=\"GBK\" ?>");
 23             sb.append("\n");
 24             sb.append("<?mso-application progid=\"Excel.Sheet\"?>");
 25             sb.append("\n");
 26             sb.append("<Workbook xmlns=\"urn:schemas-microsoft-com:office:spreadsheet\"");
 27             sb.append("\n");
 28             sb.append("  xmlns:o=\"urn:schemas-microsoft-com:office:office\"");
 29             sb.append("\n");
 30             sb.append(" xmlns:x=\"urn:schemas-microsoft-com:office:excel\"");
 31             sb.append("\n");
 32             sb.append(" xmlns:ss=\"urn:schemas-microsoft-com:office:spreadsheet\"");
 33             sb.append("\n");
 34             sb.append(" xmlns:html=\"http://www.w3.org/TR/REC-html40\">");
 35             sb.append("\n");
 36             sb.append("<DocumentProperties xmlns=\"urn:schemas-microsoft-com:office:office\"> ");
 37             sb.append("\n");
 38             sb.append(" <Styles>\n");
 39             sb.append("  <Style ss:ID=\"Default\" ss:Name=\"Normal\">\n");
 40             sb.append("   <Alignment ss:Vertical=\"Center\"/>\n");
 41             sb.append("   <Borders/>\n");
 42             sb.append("   <Font ss:FontName=\"宋体\" x:CharSet=\"134\" ss:Size=\"12\"/>\n");
 43             sb.append("   <Interior/>\n");
 44             sb.append("   <NumberFormat/>\n");
 45             sb.append("   <Protection/>\n");
 46             sb.append("  </Style>\n");
 47             sb.append(" </Styles>\n");
 48             int sheetcount = 0;
 49             int recordcount = 65535;
 50             int currentRecord = 0;
 51             int total = 100000;
 52             int col = 20;
 53             sb.append("<Worksheet ss:Name=\"Sheet0\">");
 54             sb.append("\n");
 55             sb.append("<Table ss:ExpandedColumnCount=\"" + col
 56                     + "\" ss:ExpandedRowCount=\"" + total
 57                     + "\" x:FullColumns=\"1\" x:FullRows=\"1\">");
 58             sb.append("\n");
 59             for (int i = 0; i < total; i++) {
 60                 if ((currentRecord == recordcount
 61                         || currentRecord > recordcount || currentRecord == 0)
 62                         && i != 0) {// 一个sheet写满
 63                     currentRecord = 0;
 64                     rafs.write(sb.toString().getBytes());
 65                     sb.setLength(0);
 66                     sb.append("</Table>");
 67                     sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
 68                     sb.append("\n");
 69                     sb.append("<ProtectObjects>False</ProtectObjects>");
 70                     sb.append("\n");
 71                     sb.append("<ProtectScenarios>False</ProtectScenarios>");
 72                     sb.append("\n");
 73                     sb.append("</WorksheetOptions>");
 74                     sb.append("\n");
 75                     sb.append("</Worksheet>");
 76                     sb.append("<Worksheet ss:Name=\"Sheet" + i / recordcount
 77                             + "\">");
 78                     sb.append("\n");
 79                     sb.append("<Table ss:ExpandedColumnCount=\"" + col
 80                             + "\" ss:ExpandedRowCount=\"" + recordcount
 81                             + "\" x:FullColumns=\"1\" x:FullRows=\"1\">");
 82                     sb.append("\n");
 83                 }
 84                 sb.append("<Row>");
 85                 for (int j = 0; j < col; j++) {
 86                     System.out.println(i);
 87                     sb.append("<Cell><Data ss:Type=\"String\">111</Data></Cell>");
 88                     sb.append("\n");
 89                 }
 90                 sb.append("</Row>");
 91                 if (i % 5000 == 0) {
 92                     rafs.write(sb.toString().getBytes());
 93                     rafs.flush();
 94                     sb.setLength(0);
 95                 }
 96                 sb.append("\n");
 97                 currentRecord++;
 98             }
 99             rafs.write(sb.toString().getBytes());
100             sb.setLength(0);
101             sb.append("</Table>");
102             sb.append("<WorksheetOptions xmlns=\"urn:schemas-microsoft-com:office:excel\">");
103             sb.append("\n");
104             sb.append("<ProtectObjects>False</ProtectObjects>");
105             sb.append("\n");
106             sb.append("<ProtectScenarios>False</ProtectScenarios>");
107             sb.append("\n");
108             sb.append("</WorksheetOptions>");
109             sb.append("\n");
110             sb.append("</Worksheet>");
111             sb.append("</Workbook>");
112             sb.append("\n");
113             rafs.write(sb.toString().getBytes());
114             rafs.flush();
115             rafs.close();
116         } catch (FileNotFoundException e) {
117             e.printStackTrace();
118         } catch (IOException e) {
119             e.printStackTrace();
120         }
121     }
122 }

导出xml文件之后直接修改后缀名为.xlsx就可以直接打开,弊端:无法导出.xls格式的excel文件.以上只是一种简单想法,留待以后具体实现.

扩展:既然可以使用xml文件导出excel,那么导出csv文件之后也可以直接改后缀名为.xls,目前只是一种想法,尚未证实可行性.

 

posted on 2017-04-22 10:43  vbvb520  阅读(4577)  评论(0编辑  收藏  举报

导航