大数据量下载解决方案问题描述:?????????????? 最近遇到一个很棘手的问题,信用卡网上支付的交易越来越多了
大数据量下载解决方案
问题描述:??????????????
最近遇到一个很棘手的问题,信用卡网上支付的交易越来越多了,日平均交易数量很大,并且这个数据还处在一个上升的阶段,但这仅仅是个开始。我们这边的系统负责给柜员提供一系列报表,数据量比较大,时不时的会time out,或者会om掉。
原因分析:
Time out超时现象:这个是我们系统跨另外一个系统获取数据,我们所用技术的框架有个超时设置,即一般不能超过60秒。这样设置也合情合理,换作我是客户,我也不愿意在页面提交个请求后,要等很长时间才给我个结果。
这个问题瓶颈在于我们访问后台的时间瓶颈,即我们不能耗时太长,也就是说根本不可能要求修改框架设定的超时时间。
那么怎么解决呢?我们只有要求后台分批返回这些数据。
Outof Memory内存溢出现象:这个问题是当数据量比较大的时候,下载时这些大数据占用太多内存,JAVA虚拟机报出的错误。有个直接的但不长久的解决方法,就是增大JAVA虚拟机的内存设置,但随着数据量的增长,这个解决方法就会被淘汰。
解决方案分析:
Time out问题可以和提供接口方商讨,按照分页的方式即可解决。
我们重点关注一下OM的问题吧。这里有几种解决方案:
1.????? 用POI或JXL
POI是apache公司的一个子项目,主要提供一组windows文档的Java API;
JXL是Java Excel的简称,一个开放源码的项目,通过它Java开发人员可以操作Excel??????? 文件的内容,可能它更专注些,比如名字就叫做java(不包含其他编程语言)的excel(不处理windows的其他文件),所以数据量稍大时效率以及在消耗内存方面,略胜前者一筹,这里我就不再赘述两者之间的差别了,在网络上大家可以搜索到一大箩筐关于此信息。
??????????????? if (propertyIterator.hasNext()) {??
??????????????????? csvFileOutputStream.write(",");??
??????????????? }??
??????????? }??
??????????? csvFileOutputStream.newLine();??
??????????? // 写入文件内容??
??????????? for (Iterator iterator = exportData.iterator(); iterator.hasNext();) {??
??????????????? Object row = (Object) iterator.next();??
??????????????? for (Iterator propertyIterator = rowMapper.entrySet().iterator(); propertyIterator.hasNext();) {??
??????????????????? java.util.Map.Entry propertyEntry = (java.util.Map.Entry) propertyIterator.next();??
??????????????????? csvFileOutputStream.write("/""?
??????????????????????????? + BeanUtils.getProperty(row, propertyEntry.getKey().toString()).toString() + "/"");??
??????????????????? if (propertyIterator.hasNext()) {??
??????????????????????? csvFileOutputStream.write(",");??
??????????????????? }??
??????????????? }??
??????????????? if (iterator.hasNext()) {??
??????????????????? csvFileOutputStream.newLine();??
??????????????? }??
??????????? }??
??????????? csvFileOutputStream.flush();??
??????? } catch (Exception e) {??
??????????? e.printStackTrace();??
??????? } finally {??
??????????? try {??
??????????????? csvFileOutputStream.close();??
??????????? } catch (IOException e) {??
??????????????? e.printStackTrace();??
??????????? }??
??????? }??
??????? return csvFile;??
??? }??????
}
用html方式:
/**
*html方式导出数据
*
*这个格式怎样得到呢?方法是这样:?
*你先建一个excel文件,如a.xls。填上两条伪数据。然后另存为网页,即htm格式,如a.htm。??
*然后,用记事本打开htm格式的a.htm,这样excel文件格式代码就暴露在你面前。?????
*剩下的事,就是把a.htm源代码的伪数据部分,替成数据库里的数据,然后把替换后的整个a.htm源代码,用java的io写成一个后缀为xls的文件。就打完收工了。???
*
*注意:
*为了不给内存增加压力,要把a.htm源代码分成三部分:头(伪数据部分 前的代码) + 伪数据部分 + 尾(伪数据部分 后的代码)。???
*先把 头 写到文件,并flush。
*然后是 伪数据部分 ,替一条数据库里的记录就写到文件里,并flush。
*最后把 尾 写到文件,并flush。??
*/
public class htmlAndExcel {
???
??? public static void exportToExcel(OutputStream out) throws Exception{??
?
??????? String str = "<html xmlns:o='urn:schemas-microsoft-com:office:office'"+??
??????????? "xmlns:x='urn:schemas-microsoft-com:office:excel'"+??
??????????? "xmlns='http://www.w3.org/TR/REC-html40'>"+??
??????????? "<head>"+??
??????????? "<meta http-equiv=Content-Type content='text/html; charset=gb2312'>"+??
??????????? "<meta name=ProgId content=Excel.Sheet>"+??
??????????? "<meta name=Generator content='Microsoft Excel 11'>"+??
??????????? "<link rel=File-List href='1111.files/filelist.xml'>"+??
??????????? "<link rel=Edit-Time-Data href='1111.files/editdata.mso'>"+??
??????????? "<link rel=OLE-Object-Data href='1111.files/oledata.mso'>"+??
??????????? "<!--[if gte mso 9]><xml>"+??
???????????? "<o:DocumentProperties>"+??
????????????? "<o:Created>1996-12-17T01:32:42Z</o:Created>"+??
????????????? "<o:LastSaved>2010-03-17T06:50:36Z</o:LastSaved>"+??
????????????? "<o:Version>11.5606</o:Version>"+??
???????????? "</o:DocumentProperties>"+??
???????????? "<o:OfficeDocumentSettings>"+??
????????????? "<o:RemovePersonalInformation/>"+??
???????????? "</o:OfficeDocumentSettings>"+??
??????????? "</xml><![endif]-->"+??
??????????? "<style>"+??
??????????? "<!--table"+??
??????????????? "{mso-displayed-decimal-separator:'//.';"+??
??????????????? "so-displayed-thousand-separator:'//,';}"+??
??????????? "@page"+??
??????????????? "{margin:1.0in .75in 1.0in .75in;"+??
??????????????? "mso-header-margin:.5in;"+??
??????????????? "mso-footer-margin:.5in;}"+??
??????????? "tr"+??
??????????????? "{mso-height-source:auto;"+??
??????????????? "mso-ruby-visibility:none;}"+??
??????????? "col"+??
??????????????? "{mso-width-source:auto;"+??
??????????????? "mso-ruby-visibility:none;}"+??
??????????? "br"+??
??????????????? "{mso-data-placement:same-cell;}"+??
??????????? ".style0"+??
??????????????? "{mso-number-format:General;"+??
??????????????? "text-align:general;"+??
??????????????? "vertical-align:bottom;"+??
??????????????? "white-space:nowrap;"+??
??????????????? "mso-rotate:0;"+??
??????????????? "mso-background-source:auto;"+??
??????????????? "mso-pattern:auto;"+??
??????????????? "color:windowtext;"+??
??????????????? "font-size:12.0pt;"+??
??????????????? "font-weight:400;"+??
??????????????? "font-style:normal;"+??
??????????????? "text-decoration:none;"+??
??????????????? "font-family:宋体;"+??
??????????????? "mso-generic-font-family:auto;"+??
??????????????? "mso-font-charset:134;"+??
??????????????? "border:none;"+??
??????????????? "mso-protection:locked visible;"+??
??????????????? "mso-style-name:常规;"+??
??????????????? "mso-style-id:0;}"+??
??????????? "td"+??
??????????????? "{mso-style-parent:style0;"+??
??????????????? "padding-top:1px;"+??
??????????????? "padding-right:1px;"+??
??????????????? "padding-left:1px;"+??
??????????????? "mso-ignore:padding;"+??
??????????????? "color:windowtext;"+??
??????????????? "font-size:12.0pt;"+??
??????????????? "font-weight:400;"+??
??????????????? "font-style:normal;"+??
??????????????? "text-decoration:none;"+??
??????????????? "font-family:宋体;"+??
??????????????? "mso-generic-font-family:auto;"+??
??????????????? "mso-font-charset:134;"+??
??????????????? "mso-number-format:General;"+??
??????????????? "text-align:general;"+??
??????????????? "vertical-align:bottom;"+??
??????????????? "border:none;"+??
??????????????? "mso-background-source:auto;"+??
??????????????? "mso-pattern:auto;"+??
??????????????? "mso-protection:locked visible;"+??
??????????????? "white-space:nowrap;"+??
??????????????? "mso-rotate:0;}"+??
??????????? "ruby"+??
??????????????? "{ruby-align:left;}"+??
??????????? "rt"+??
??????????????? "{color:windowtext;"+??
??????????????? "font-size:9.0pt;"+??
??????????????? "font-weight:400;"+??
??????????????? "font-style:normal;"+??
??????????????? "text-decoration:none;"+??
??????????????? "font-family:宋体;"+??
??????????????? "mso-generic-font-family:auto;"+??
??????????????? "mso-font-charset:134;"+??
??????????????? "mso-char-type:none;"+??
??????????????? "display:none;}"+??
??????????? "-->"+??
??????????? "</style>"+??
??????????? "<!--[if gte mso 9]><xml>"+??
???????????? "<x:ExcelWorkbook>"+??
????????????? "<x:ExcelWorksheets>"+??
?????????????? "<x:ExcelWorksheet>"+??
??????????????? "<x:Name>Sheet1</x:Name>"+??
??????????????? "<x:WorksheetOptions>"+??
???????????????? "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+??
???????????????? "<x:CodeName>Sheet1</x:CodeName>"+??
???????????????? "<x:Selected/>"+??
???????????????? "<x:Panes>"+??
????????????????? "<x:Pane>"+??
?????????????????? "<x:Number>3</x:Number>"+??
?????????????????? "<x:ActiveRow>4</x:ActiveRow>"+??
?????????????????? "<x:ActiveCol>4</x:ActiveCol>"+??
????????????????? "</x:Pane>"+??
???????????????? "</x:Panes>"+??
???????????????? "<x:ProtectContents>False</x:ProtectContents>"+??
???????????????? "<x:ProtectObjects>False</x:ProtectObjects>"+??
???????????????? "<x:ProtectScenarios>False</x:ProtectScenarios>"+??
??????????????? "</x:WorksheetOptions>"+??
?????????????? "</x:ExcelWorksheet>"+??
?????????????? "<x:ExcelWorksheet>"+??
??????????????? "<x:Name>Sheet2</x:Name>"+??
??????????????? "<x:WorksheetOptions>"+??
???????????????? "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+??
???????????????? "<x:CodeName>Sheet2</x:CodeName>"+??
???????????????? "<x:ProtectContents>False</x:ProtectContents>"+??
???????????????? "<x:ProtectObjects>False</x:ProtectObjects>"+??
???????????????? "<x:ProtectScenarios>False</x:ProtectScenarios>"+??
??????????????? "</x:WorksheetOptions>"+??
?????????????? "</x:ExcelWorksheet>"+??
?????????????? "<x:ExcelWorksheet>"+??
??????????????? "<x:Name>Sheet3</x:Name>"+??
??????????????? "<x:WorksheetOptions>"+??
???????????????? "<x:DefaultRowHeight>285</x:DefaultRowHeight>"+??
???????????????? "<x:CodeName>Sheet3</x:CodeName>"+??
???????????????? "<x:ProtectContents>False</x:ProtectContents>"+??
???????????????? "<x:ProtectObjects>False</x:ProtectObjects>"+??
???????????????? "<x:ProtectScenarios>False</x:ProtectScenarios>"+??
??????????????? "</x:WorksheetOptions>"+??
?????????????? "</x:ExcelWorksheet>"+??
????????????? "</x:ExcelWorksheets>"+??
????????????? "<x:WindowHeight>4530</x:WindowHeight>"+??
????????????? "<x:WindowWidth>8505</x:WindowWidth>"+??
????????????? "<x:WindowTopX>480</x:WindowTopX>"+??
????????????? "<x:WindowTopY>120</x:WindowTopY>"+??
????????????? "<x:AcceptLabelsInFormulas/>"+??
????????????? "<x:ProtectStructure>False</x:ProtectStructure>"+??
????????????? "<x:ProtectWindows>False</x:ProtectWindows>"+??
???????????? "</x:ExcelWorkbook>"+??
??????????? "</xml><![endif]-->"+??
??????????? "</head>"+??
??????????? "<body link=blue vlink=purple>";??
??????? str += "<table x:str border=0 cellpadding=0 cellspacing=0 width=144 style='border-collapse:collapse;table-layout:fixed;width:108pt'>"+??
???????????? "<col width=72 span=2 style='width:54pt'>";??
??????? int count = 1000;??
??????? while (count>0) {??
??????????? str += "<tr height=19 style='height:14.25pt'>"+??
????????????? "<td height=19 align=right width=72 style='height:14.25pt;width:54pt' x:num>"+count+"</td>"+??
????????????? "<td width=72 style='width:54pt'>"+"仅仅为了测试,^_^"+"</td>"+??
???????????? "</tr>";??
??????????? count--;
??????? }??
??????? str += "<![endif]>"+??
??????????? "</table>"+??
??????????? "</body>"+??
??????????? "</html";??
??????? System.out.println(str);??
??????? out.write(str.getBytes());??
??????? out.close();????
??? }?
}
结论:
综合上述几种分析,由于项目的特点,暂时采用读取内容到csv文件中,用户可以用xls方式打开。2003版本的excel单sheet是只能65535行,
我们在程序中判断,当达到10000条数据时,就要new sheet.
?