测试共同条件:
数据总数为110011条,每条数据条数为19个字段。
电脑配置为:P4 2.67GHz,1G内存。
一、POI、JXL、FastExcel比较
POI、JXL、FastExcel均为java第三方开源导出Excel的开源项目。
导出方案一:一次性全部导出到一个Excel文件中。
实际情况均报OutOfMemery错误,以下数据为报OutOfMemery数据时,数据到的最大数据数目,如表1所示:
表1:报OutOfMemery错误时所能处理的数据量
FastExecl POI JXL
10000数据/sheet 37465 28996 42270
5000数据/sheet 39096 31487 46270
3000数据/sheet 39000 32493 47860
小结:
多分sheet能一定程度上减少内存的使用,但是均因为程序中创建的Cell(即为Excel中的一个单元格)无法释放,消耗大量内存,导致OutOfMemery错误;JXL表现最好,创建Cell内存使用较少。
导出方案二:先分多个Excel文件将数据全部导出,然后对多个Excel文件进行合并。
首先,测试将全部数据导出所用的时间,如表2所示,数据均测试三次取平均。
表2:导出全部数据所用时间
FastExecl POI JXL
10000数据/文件 68s 33s 30s
5000数据/文件 68s 32s 33s
3000数据/文件 59s 33s 39s
小结:
均成功导出Excel文件,原因是导出一个Excel文件,释放所占用的创建Cell的内存。
FastExecl表现最差,POI表现稳定,JXL随着数据的增大,速度一定程度上增快。
然后,进行整合,由于将多Excel合并成一个Excel文件的功能只有POI所有,故使用POI测试,结果如表3所示。
注:数据量大合并还会报OutOfMemery错误,故合并总数据量以5万为准。
表3:合并5万数据所用时间
时间
10000数据/文件 11s
5000数据/文件 11s
3000数据/文件 11s
小结:
使用POI对文件进行合并速度较快,但有数据量的限制。
总结:方案二比较可行,但是数据量有限制,为5万条。
二、导出XML 的电子表格
导出的格式类似为纯文本,能实现大数据量的存储,并能实现分Sheet查看,且能添加简单的样式,符合项目要求。经实际测试Excel2003和Excel2007均能识别并正常打开查看。使用时间测试如表4所示,数据均测试3次取平均。
表4:生成全部数据所用时间
时间
10000数据/sheet 28.0秒
20000数据/sheet 30.1秒
30000数据/sheet 28.1秒
40000数据/sheet 26.5秒
50000数据/sheet 28.2秒
55000数据/sheet 26.8秒
59000数据/sheet 30.1秒
59500数据/sheet 发生假死机现象
60000数据/sheet 发生假死机现象
但是导出的数据为XML不是纯正的Excel文件,如使用Excel文件的xls后缀保存,打开文件会弹出警告,但不影响阅读。
且经实际测试,在Access2007和Access2003中可通过导入外部数据的方式,将导出的XML导入进Access数据库。
三、总结
项目要求是大数据量导出Excel文件,POI、JXL、FastExcel不能完全满足要求;使用XML 的电子表格导出实现了大数据量导出,但是格式为XML不是纯正的Excel文件,为曲线救国。两种导出形式的比较,如表5所示。
表5:合并5万数据所用时间
POI、JXL、FastExcel XML 的电子表格
导出数据格式 为纯Execl文件 为XML文件
导出数据量 小 较大
能否分Sheet 能 能
能否添加样式 能 能
能否添加图片 POI 能 不能
导出数据能否导入Access 能 能
tidus2005 写道
biguan 写道
我同事最近要把1000万条记录从数据库导到excel里,在我的帮助下解决了。
呵呵。原创的。
因每个excel最多放5万条,所以他把这1000万条记录记录放到了200个excel文件里。用时40分钟。
采用基本的jdbc技术+io流。
1.先进一个excel文件。填上要的表头和两条记录。然后另存为网页a.html。
2.用记事本打开网页a.html,就看到源代码。把源代码分成三部分:头+记录行+尾。
3.用jdbc访问数据库,循环遍历,每5万条,用io流写文件,格式为"xxx.xls”。
a.html的头代码+记录行代码(已经被5万条替换)+尾代码。
没有看太懂你的意思, 用html是干什么?
用java的io写txt格式的文件,大家都会吧?
其实,也可以用java的io写xls格式的文件的。关键是你得按一定的excel文件格式写,才能保证生成的是excel文件。
这个格式怎样得到呢?方法是这样:
你先建一个excel文件,如a.xls。填上两条伪数据。然后另存为网页,即htm格式,如a.htm。
然后,用记事本打开htm格式的a.htm,这样excel文件格式代码就暴露在你面前。
剩下的事,呵呵,就是把a.htm源代码的伪数据部分,替成数据库里的数据,然后把替换后的整个a.htm源代码,用java的io写成一个后缀为xls的文件。就打完收工了。
注意:为了不给内存增加压力,要把a.htm源代码分成三部分:头(伪数据部分 前的代码) + 伪数据部分 + 尾(伪数据部分 后的代码)。
先把 头 写到文件,并flush。然后是 伪数据部分 ,替一条数据库里的记录就写到文件里,并flush。最后把 尾 写到文件,并flush。
这里有另一个解决方案,这里讨论简单的解决方案
大数据量导出Excel的方案,顾名思义是要导出大量的数据,
大量数据导出本身就带有风险,因为很大的数据量比如*G的文件根本不可能用
excel来打开,就算打开了也是无法查看的,
我们做一个简单的计算
excel 07之前每个标签最多有256*65536的数据量,好像最多也是256个标签,
也就是说最多可以存储65536*65536个字段的数据量,也差不多能满足一般的数据的存储。。(有点矛盾)
但是存了这么多数据的电子表格能打开吗?。。。
下面说说导出这么大量数据的解决方案,在另一个文章里提到的方式就不用再提了。
1、用csv导出
写一个导出数据的程序,把需要的数据导出,并把输出结果输出到csv文件,每个字段之间做好分隔符,
这样可以直接打开就是excel来打开的。
如果非要存到excel里,还有一种办法,
新建一个excel文件,选择一个标签, 然后在菜单栏里选择 数据->导入外部数据->外部数据
弹出文件选择框,选择csv文件,弹出 【文件导入向导】 选择 【分隔符号】下一步,
然后接下来的对话框里选择自己定义好的分隔符 比如【;】【###】等,选择后下面的
数据预览里就可以看到数据分割后的结果,选择完成,然后选择一个标签中的某个单元格就可以。
2、使用toad工具
toad支持主流的数据库,像oracle,mysql,mssql等,下载对应的软件安装。
新建一个查询窗口,写好sql语句后执行。
在查询结果里选中需要导出的数据,右键选中export 之类的菜单,具体步骤就不用细说了,
可以直接导出为excel,还有其他的一些文件格式。有时间再总结一下,本人电脑没装toad工具
所以不能一步一步的说怎么导出,但是确实可行的方法,而且我自己也测试过,而且导出时很灵活,
设定分隔符什么的,如果需要格式化数据,,那就在sql语句里直接格式化,都格式化成字符串格式,
这样导出时处理起来比较方便,比如oracle德 to_char,concat 之类的函数。反正需要根据自己的需要
灵活的应用就好了。
3、其他数据浏览工具
比如oracle的plsql ,写一个sql语句,得出结果之后把所有数据选中,直接复制,ctrl+c也可以。
新建一个excel文档,直接粘贴,一般都是已经分割好的,一个单元格一个字段的数据,excel可以识别一般的
分隔符,比如 ; \t 等分隔符,如果不行 就按照1中的办法,
就是繁琐一些,但是很好用。
最近总结出来的就是这些,以后有更好的办法就直接分享。
有其他好的解决方案的,请留言一起探讨,哪天有这类的程序就把代码贴出来分享,
开始工作了,已经耽误8分钟了。希望项目经理不要知道我偷懒。
下面来个自己写的例子吧:
package syscz.net.cn.dao.impl; import java.io.File; import java.io.FileWriter; import java.io.IOException; import java.sql.SQLException; import java.text.SimpleDateFormat; import java.util.ArrayList; import syscz.net.cn.bean.ConstPage; import syscz.net.cn.bean.HTczBean; import syscz.net.cn.bean.HtRbean; import syscz.net.cn.util.BaseDAO; public class HtczDAOImpl extends BaseDAO { private ArrayList brandList; private ArrayList list; private HtRbean r = null; private ArrayList listName; /** * 合同统计 */ public ConstPage getAllMsg(String[] name, String sql, ConstPage page) { brandList = new ArrayList(); con = this.getConnection(); listName = new ArrayList(); int cont = 0 ; if(page.getStart()== 1){ cont =name.length; for(int i = 0; i < cont; i++){ listName.add(name[i].trim()); } }else{ listName = page.getListName(); } page.setTotalCount(cont); try { System.out.println("page.getPageSize():"+page.getPageSize()); System.out.println("listName.size():"+listName.size()); int pe = page.getPageSize() ; if(listName.size()<page.getPageSize()*page.getStart()){ pe = listName.size(); } for (int i = page.getPageSize()*page.getStart()-page.getPageSize(); i < pe; i++) { String sql2 = "select * from htcz where 1=1 and BName='" + listName.get(i) + "' " + sql; pstmt = con.prepareStatement(sql2); rs = pstmt.executeQuery(); r = new HtRbean(); r.setName(name[i]); list = new ArrayList(); while (rs.next()) { HTczBean b = new HTczBean(); b.setId(rs.getString("HTid")); b.setHtId(rs.getString("HTNo")); b.setHtName(rs.getString("HTName")); b.setHtFpno(rs.getString("HTFPNo")); b.setHdFY(rs.getString("BHD")); b.setHdTime(rs.getString("HTHDTime")); b.setYjFY(rs.getString("BYJ")); b.setBjsTime(rs.getString("BJSTime")); list.add(b); r.setList(list); } brandList.add(r); } } catch (SQLException e) { e.printStackTrace(); } finally { this.closeDB(); } page.setListName(listName); page.setResult(brandList); return page; } public void outP(String[] name, String sql){ File myFilePathlo = new File("C:/ZHANGYM"); if(!myFilePathlo.exists()){ myFilePathlo.mkdirs(); } try { SimpleDateFormat tempDate = new SimpleDateFormat("yyyy-MM-dd HHmmss"); String datetime = tempDate.format(new java.util.Date()); File filelo = new File("C:/ZHANGYM/"+datetime+".xls"); if(!filelo.exists()){ FileWriter wr = new FileWriter(filelo); wr.write("<html xmlns:v='urn:schemas-microsoft-com:vml' "); wr.write("xmlns:o='urn:schemas-microsoft-com:office:office' "); wr.write("xmlns:x='urn:schemas-microsoft-com:office:excel' "); wr.write("xmlns='http://www.w3.org/TR/REC-html40'> "); wr.write(" "); wr.write("<head> "); wr.write("<meta http-equiv=Content-Type content='text/html; charset=gb2312'> "); wr.write("<meta name=ProgId content=Excel.Sheet> "); wr.write("<meta name=Generator content='Microsoft Excel 11'> "); wr.write("<link rel=File-List href='aa.files/filelist.xml'> "); wr.write("<link rel=Edit-Time-Data href='aa.files/editdata.mso'> "); wr.write("<link rel=OLE-Object-Data href='aa.files/oledata.mso'> "); wr.write("<!--[if gte mso 9]><xml> "); wr.write(" <o:DocumentProperties> "); wr.write(" <o:Created>1996-12-17T01:32:42Z</o:Created> "); wr.write(" <o:LastSaved>2011-04-03T03:43:17Z</o:LastSaved> "); wr.write(" <o:Version>11.9999</o:Version> "); wr.write(" </o:DocumentProperties> "); wr.write(" <o:OfficeDocumentSettings> "); wr.write(" <o:RemovePersonalInformation/> "); wr.write(" </o:OfficeDocumentSettings> "); wr.write("</xml><![endif]--> "); wr.write("<style> "); wr.write("<!--table "); wr.write(" {mso-displayed-decimal-separator:'\\.'; mso-displayed-thousand-separator:'\\,';} "); wr.write("@page "); wr.write(" {margin:1.0in .75in 1.0in .75in; "); wr.write(" mso-header-margin:.5in; "); wr.write(" mso-footer-margin:.5in;} "); wr.write("tr "); wr.write(" {mso-height-source:auto; "); wr.write(" mso-ruby-visibility:none;} "); wr.write("col "); wr.write(" {mso-width-source:auto; "); wr.write(" mso-ruby-visibility:none;} "); wr.write("br "); wr.write(" {mso-data-placement:same-cell;} "); wr.write(".style0 "); wr.write(" {mso-number-format:General; "); wr.write(" text-align:general; "); wr.write(" vertical-align:bottom; "); wr.write(" white-space:nowrap; "); wr.write(" mso-rotate:0; "); wr.write(" mso-background-source:auto; "); wr.write(" mso-pattern:auto; "); wr.write(" color:windowtext; "); wr.write(" font-size:12.0pt; "); wr.write(" font-weight:400; "); wr.write(" font-style:normal; "); wr.write(" text-decoration:none; "); wr.write(" font-family:宋体; "); wr.write(" mso-generic-font-family:auto; "); wr.write(" mso-font-charset:134; "); wr.write(" border:none; "); wr.write(" mso-protection:locked visible; "); wr.write(" mso-style-name:常规; "); wr.write(" mso-style-id:0;} "); wr.write("td "); wr.write(" {mso-style-parent:style0; "); wr.write(" padding-top:1px; "); wr.write(" padding-right:1px; "); wr.write(" padding-left:1px; "); wr.write(" mso-ignore:padding; "); wr.write(" color:windowtext; "); wr.write(" font-size:12.0pt; "); wr.write(" font-weight:400; "); wr.write(" font-style:normal; "); wr.write(" text-decoration:none; "); wr.write(" font-family:宋体; "); wr.write(" mso-generic-font-family:auto; "); wr.write(" mso-font-charset:134; "); wr.write(" mso-number-format:General; "); wr.write(" text-align:general; "); wr.write(" vertical-align:bottom; "); wr.write(" border:none; "); wr.write(" mso-background-source:auto; "); wr.write(" mso-pattern:auto; "); wr.write(" mso-protection:locked visible; "); wr.write(" white-space:nowrap; "); wr.write(" mso-rotate:0;} "); wr.write(".xl24 "); wr.write(" {mso-style-parent:style0; "); wr.write(" text-align:center;} "); wr.write("ruby "); wr.write(" {ruby-align:left;} "); wr.write("rt "); wr.write(" {color:windowtext; "); wr.write(" font-size:9.0pt; "); wr.write(" font-weight:400; "); wr.write(" font-style:normal; "); wr.write(" text-decoration:none; "); wr.write(" font-family:宋体; "); wr.write(" mso-generic-font-family:auto; "); wr.write(" mso-font-charset:134; "); wr.write(" mso-char-type:none; "); wr.write(" display:none;} "); wr.write("--> "); wr.write("</style> "); wr.write("<!--[if gte mso 9]><xml> "); wr.write(" <x:ExcelWorkbook> "); wr.write(" <x:ExcelWorksheets> "); wr.write(" <x:ExcelWorksheet> "); wr.write(" <x:Name>Sheet1</x:Name> "); wr.write(" <x:WorksheetOptions> "); wr.write(" <x:DefaultRowHeight>285</x:DefaultRowHeight> "); wr.write(" <x:Print> "); wr.write(" <x:ValidPrinterInfo/> "); wr.write(" <x:PaperSizeIndex>9</x:PaperSizeIndex> "); wr.write(" <x:HorizontalResolution>600</x:HorizontalResolution> "); wr.write(" <x:VerticalResolution>600</x:VerticalResolution> "); wr.write(" </x:Print> "); wr.write(" <x:CodeName>Sheet1</x:CodeName> "); wr.write(" <x:Selected/> "); wr.write(" <x:Panes> "); wr.write(" <x:Pane> "); wr.write(" <x:Number>3</x:Number> "); wr.write(" <x:ActiveRow>4</x:ActiveRow> "); wr.write(" <x:ActiveCol>6</x:ActiveCol> "); wr.write(" </x:Pane> "); wr.write(" </x:Panes> "); wr.write(" <x:ProtectContents>False</x:ProtectContents> "); wr.write(" <x:ProtectObjects>False</x:ProtectObjects> "); wr.write(" <x:ProtectScenarios>False</x:ProtectScenarios> "); wr.write(" </x:WorksheetOptions> "); wr.write(" </x:ExcelWorksheet> "); wr.write(" <x:ExcelWorksheet> "); wr.write(" <x:Name>Sheet2</x:Name> "); wr.write(" <x:WorksheetOptions> "); wr.write(" <x:DefaultRowHeight>285</x:DefaultRowHeight> "); wr.write(" <x:CodeName>Sheet2</x:CodeName> "); wr.write(" <x:ProtectContents>False</x:ProtectContents> "); wr.write(" <x:ProtectObjects>False</x:ProtectObjects> "); wr.write(" <x:ProtectScenarios>False</x:ProtectScenarios> "); wr.write(" </x:WorksheetOptions> "); wr.write(" </x:ExcelWorksheet> "); wr.write(" <x:ExcelWorksheet> "); wr.write(" <x:Name>Sheet3</x:Name> "); wr.write(" <x:WorksheetOptions> "); wr.write(" <x:DefaultRowHeight>285</x:DefaultRowHeight> "); wr.write(" <x:CodeName>Sheet3</x:CodeName> "); wr.write(" <x:ProtectContents>False</x:ProtectContents> "); wr.write(" <x:ProtectObjects>False</x:ProtectObjects> "); wr.write(" <x:ProtectScenarios>False</x:ProtectScenarios> "); wr.write(" </x:WorksheetOptions> "); wr.write(" </x:ExcelWorksheet> "); wr.write(" </x:ExcelWorksheets> "); wr.write(" <x:WindowHeight>4530</x:WindowHeight> "); wr.write(" <x:WindowWidth>8505</x:WindowWidth> "); wr.write(" <x:WindowTopX>480</x:WindowTopX> "); wr.write(" <x:WindowTopY>120</x:WindowTopY> "); wr.write(" <x:AcceptLabelsInFormulas/> "); wr.write(" <x:ProtectStructure>False</x:ProtectStructure> "); wr.write(" <x:ProtectWindows>False</x:ProtectWindows> "); wr.write(" </x:ExcelWorkbook> "); wr.write("</xml><![endif]--><!--[if gte mso 9]><xml> "); wr.write(" <o:shapedefaults v:ext='edit' spidmax='1027'/> "); wr.write("</xml><![endif]--> "); wr.write("</head> "); wr.write(" "); wr.write("<body link=blue vlink=purple> "); wr.write(" "); wr.write("<table x:str border=0 cellpadding=0 cellspacing=0 width=394 style='border-collapse: "); wr.write(" collapse;table-layout:fixed;width:296pt'> "); wr.write(" <col width=102 style='mso-width-source:userset;mso-width-alt:3264;width:77pt'> "); wr.write(" <col width=76 style='mso-width-source:userset;mso-width-alt:2432;width:57pt'> "); wr.write(" <col width=72 span=3 style='width:54pt'> "); wr.write(" <tr height=19 style='height:14.25pt'> "); wr.write(" <td colspan=5 height=19 class=xl24 width=394 style='height:14.25pt; "); wr.write(" width:296pt' x:num>产值统计,导出日期为:"+datetime+"</td> "); wr.write(" </tr> "); wr.write(" <tr height=19 style='height:14.25pt'> "); con = this.getConnection(); for (int i = 0; i < name.length; i++) { String sql2 = "select * from htcz where 1=1 and BName='" + name[i].trim() + "' " + sql; pstmt = con.prepareStatement(sql2); rs = pstmt.executeQuery(); while (rs.next()) { wr.write("<tr>"); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+name[i]+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("HTid")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("HTNo")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("HTName")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("HTFPNo")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("BHD")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("HTHDTime")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("BYJ")+"</td> "); wr.write(" <td height=19 align=right style='height:14.25pt' x:num>"+rs.getString("BJSTime")+"</td> "); wr.write("</tr>"); } } wr.write(" <td colspan=3 style='mso-ignore:colspan'></td> "); wr.write(" </tr> "); wr.write(" <![if supportMisalignedColumns]> "); wr.write(" <tr height=0 style='display:none'> "); wr.write(" <td width=102 style='width:77pt'></td> "); wr.write(" <td width=76 style='width:57pt'></td> "); wr.write(" <td width=72 style='width:54pt'></td> "); wr.write(" <td width=72 style='width:54pt'></td> "); wr.write(" <td width=72 style='width:54pt'></td> "); wr.write(" </tr> "); wr.write(" <![endif]> "); wr.write("</table> "); wr.write(" "); wr.write("</body> "); wr.write(" "); wr.write("</html> "); wr.write(" "); wr.close(); } System.out.println("导出完成请在!C:/ZHANGYM/下找相应日期文件!"); } catch (Exception e) { e.printStackTrace(); System.out.println("文件写入时有错!"); } } }