现在网上基本方法是:
1.使用CSV下载。
2.调大JVM ,Tomcat的内存。目前这两种方法客户都不同意,大家还有什么方法吗?
1.使用CSV下载。
2.调大JVM ,Tomcat的内存。目前这两种方法客户都不同意,大家还有什么方法吗?
解决方案 »
- 使用hibernate查询时出现列名无效????
- hibernate 三个表关联查询问题,求解
- 求高手~web项目图片在线显示
- 熟悉validator的mask验证的朋友请帮忙看看,在线等待
- 安装WEBLOGC的问题
- 请大家帮我看下这个出错的问题,谢谢了!
- java web 中使用JOptionConfirmDdialog()
- 127.0.0.1:8080能访问。。。为什么用机器的ip(如202.252.123.123)不行——在线等
- Activex在JSP中的使用
- 已经将一个bean设置为session,那么在其他页面还需要申明吗?
- 如何根据元素id获取xml文件中指定元素的值
- 毕业设计做什么样的项目好???
不知道能不能满足要求,不能的话就txt保存,不过可能文件过大,打开较慢
那应该也不难。你可以每次都加载那一个Excel文件,并加载第一个Sheet,分页加载的数据每次都从这个Sheet的最后一行开始添加,这样就OK了。
大哥,先读后写,文件越搞越大,POI还是把以前的内容读进去了,最后还是溢出。
我试下2万行还可以,三万就不行。我的目标是6万,你有办法吗?
我觉得内存溢出是因为加载了太多的Model,而非加载Excel文件导致的。
一个Excel文件才多大啊。我曾经加载过一个3G左右的电影文件都没有问题。
这句话能否延伸一下,不太明白。另外数据嘛,我是取出来放list,别说六万,十万行都没有报溢出错。异常是在用POI做Excel文件时产生的。
对了,你要先确定是Java报的内存溢出,而不是数据库报的内存溢出,Oracle加载的数据多的话也可能报内存溢出的。如果是Java报的内存溢出,那么就按我的思路解决应该就可以。你用的是Hibernate之类的框架,查询出来一个List的吧。List里边存放的是封装的Java对象,是这样吗?
我尝试过了用循环直接生成,分段生成不断读写文件两种方式,总是回报java.lang.OutOfMemoryError: Java heap space这个异常。
我首先参考了网上的方案,但他是基于POI3.1的,到我的POI3.5中好多API不可用了。如前所述,我采用分段方式后,生成了临时文件,再进行合并时发现目标文件会越来越大,最终还是导致了溢出。
大哥,这么干客户是不会同意的。
他们需要这样的解决方案:
1.一个XLS文件下载。
2.若数据少于6万行,只做成一个Sheet。
3.大于6万行,以6万为单位分Sheet存放。可惜小弟目前还只在26000行左右徘徊。
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
<tr><td>1</td><td>2</td><td>3</td><td>4</td></tr>
</table>
不知道他们用这个excel数据还做后续操作不,如果只是看看,这样可以吧。
还有一个操作是读取进来,也是用POI。晕啊。
制成excel无论怎么操作最后都是统一优先load到内存最后写进去,这时候数据量大就会爆掉。
只有一种变相的解决办法就是满多少数据重新生成一个临时excel最后再合并,但我不知道怎么实现
不同意就让他们自己去搞。
当时的解决办法是改成csv,别的没办法。
2.若数据少于6万行,只做成一个Sheet。
3.大于6万行,以6万为单位分Sheet存放。
就是读到的数据不放入list,直接放到cell里呀,只是生成时间有点长罢了。
10W条的数据大概要20多S,就用poi。
数据库查出来直接放cell,还能容纳10W条而不出溢出错?太强了,给代码看看呗。
这种方法我还真没试过,楼主试下发个结论出来。
不知道微软自己如何搞的,楼主找找有木有c语言导出excel的例子,如果有的话,可以封装成dll用jni调用试试。
一个cell一个cell的new呀,为什么会溢出呢?import java.sql.ResultSet;
import java.sql.SQLException;import org.apache.poi.hssf.usermodel.HSSFCell;
import org.apache.poi.hssf.usermodel.HSSFRow;
import org.apache.poi.hssf.usermodel.HSSFSheet;
import org.apache.poi.hssf.usermodel.HSSFWorkbook;public class infoExportExcel {
/**
*
* @param intRowCount 总行数
* @param sheetCount 一个sheet表内的行数
* @param wb excel
* @param sheetname sheet表名
* @param columNumber 列数
* @param tableHeader 表头名
* @param rs 查询结果集
* @throws SQLException
*/
public infoExportExcel(int intRowCount, int sheetCount, HSSFWorkbook wb, String sheetname, int columNumber, String[] tableHeader, ResultSet rs) throws SQLException{
int allSheetCount = (intRowCount + sheetCount -1)/sheetCount; //计算总工作表数,分表
if(allSheetCount > 1){ //分多个sheet表来显示
int q = 0;//sheet数
while(q < allSheetCount ){
HSSFSheet sheet = wb.createSheet(sheetname + q); //sheet表名依次为表0、表1、表2...
HSSFRow rowHeader = null;//表头
rowHeader = sheet.createRow(0);
for(int u = 0; u < columNumber; u++){
HSSFCell headerCell = rowHeader.createCell(u);
headerCell.setCellValue(tableHeader[u]);
}
int p = 1; //行
HSSFRow rowData = null;//表内容
while(rs.next() && p < sheetCount){
rowData = sheet.createRow(p);
HSSFCell cellData = null;
for(int j = 0; j < columNumber; j++){
cellData = rowData.createCell(j);
cellData.setCellValue(rs.getString(j + 1));
}
p++;
if(p > sheetCount){//大于行数后,下一个sheet表从1继续开始
p = 1;
}
}
q++;
}
}else{
HSSFSheet sheet = wb.createSheet(sheetname);
HSSFRow rowHeader = null;
rowHeader = sheet.createRow(0);
for(int u = 0; u < columNumber; u++){
HSSFCell headerCell = rowHeader.createCell(u);
headerCell.setCellValue(tableHeader[u]);
}
int p = 1;
HSSFRow rowData = null;
while(rs.next() && p < (intRowCount + 1)){
rowData = sheet.createRow(p);
HSSFCell cellData = null;
for(int j = 0; j < columNumber; j++){
cellData = rowData.createCell(j);
cellData.setCellValue(rs.getString(j + 1));
}
p++;
}
}
}}
请问你一个Sheet中最多能放多少行?
你觉得哪里有问题?这个代码在我这里没问题呀,之前写的时候没想过那么多条,后来要求分表显示的时候才加上了一个判断,可以正确导出
1.请问你设置服务器内存大小了吗?
2.>>你不是说导出excel下载出现问题么?怎么又读取了= =~~
这个我是去测试读一个大文件会不会发生溢出现象。3.>>你觉得哪里有问题?这个代码在我这里没问题呀,之前写的时候没想过那么多条,后来要求分表显示的时候才加上了一个判断,可以正确导出
问题就在这里了,不能理解为何先读到一个List再输出XLS会错 而 读出记录后直接写就没有问题。
3,嗯,年前好像也跟人讨论过这个问题,他也是先放到list里,然后就会报溢出。好像就是21楼吧。
嗯,可能还是哪里有限制吧。
Servlet代码:public class DownloadServlet extends HttpServlet {
private static final long serialVersionUID = 56890894234786L;
public void doPost(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
String fileName="download.xls";
response.setHeader("Content-disposition", "attachment; filename="+fileName);// 设定输出文件头
response.setContentType("application/msexcel");// 定义输出类型
try{
int rowCount=Integer.parseInt(request.getParameter("rowCount"));
// 表头行
String[] headers=new String[]{"更新ID","账期","基站编号","基站名称","站点状态","部门名称","站点类型","占用类型","预提(元)","未核销金额","上期未核销","开始月份","结束月份","上期抄表数","本期抄表数","电价","电量","本期报账(元)","补提(元)","预提汇总(元)","成本中心","专业","本期报账单号","基站类别","线损"};
DownloadService service=new DownloadService(); HSSFWorkbook workbook=service.generateWorkbook(rowCount, headers.length);
// 输出部分
OutputStream os = response.getOutputStream();// 取得输出流
workbook.write(os);
os.flush();
os.close();
}catch(Exception ex){
ex.printStackTrace();
}
return ;
}
public void doGet(HttpServletRequest request, HttpServletResponse response)
throws ServletException, java.io.IOException {
doPost(request, response);
}
}Service代码:public class DownloadService{
/**
* 生成工作簿对象
* @param rowCount
* @param columnCount
* @return
*/
public HSSFWorkbook generateWorkbook(int rowCount,int columnCount){
HSSFWorkbook workbook = new HSSFWorkbook(); //产生工作簿对象
HSSFSheet sheet = workbook.createSheet(); //产生工作表对象
String value=null;
for(int i=0;i<rowCount;i++){
HSSFRow row = sheet.createRow(i);//创建一行
for(int j=0;j<columnCount;j++){
value=""+i+","+j;
HSSFCell cell = row.createCell(j);
cell.setCellValue(value);
cell=null;
}
}
return workbook;
}
}
BufferedOutputStream bos = new BufferedOutputStream(out);
wb.write(bos);
at org.apache.poi.poifs.storage.DocumentBlock.<init>(DocumentBlock.java:84)
at org.apache.poi.poifs.storage.DocumentBlock.<init>(DocumentBlock.java:70)
at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:158)
at org.apache.poi.poifs.filesystem.POIFSDocument.<init>(POIFSDocument.java:182)
at org.apache.poi.poifs.filesystem.DirectoryNode.createDocument(DirectoryNode.java:309)
at org.apache.poi.poifs.filesystem.POIFSFileSystem.createDocument(POIFSFileSystem.java:265)
at org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1157)
at com.heyang.action.DownloadServlet.doPost(DownloadServlet.java:47)
at com.heyang.action.DownloadServlet.doGet(DownloadServlet.java:60)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:690)
at javax.servlet.http.HttpServlet.service(HttpServlet.java:803)
at org.apache.catalina.core.ApplicationFilterChain.internalDoFilter(ApplicationFilterChain.java:290)
at org.apache.catalina.core.ApplicationFilterChain.doFilter(ApplicationFilterChain.java:206)
at org.apache.catalina.core.StandardWrapperValve.invoke(StandardWrapperValve.java:228)
at org.apache.catalina.core.StandardContextValve.invoke(StandardContextValve.java:175)
at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:128)
at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:104)
at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109)
at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:216)
at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:844)
at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:634)
at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:445)
at java.lang.Thread.run(Unknown Source)
我这边的做法是excel压缩成zip,然后下载。
因为我这边excel内容的特殊性,压缩后可以减少非常大的空间
java.lang.OutOfMemoryError: Java heap space
大家一起研究研究,该如何解决呢?
楼主,现在解决了吗?
如果把应用程序部署到服务器上,由于服务器性能原因,基本上能够满
足客户需求,暂时没出现过内存溢出现象,所以我建议你去服务器上试试(
开大JVM内存也可以试试,悄悄的,不给他说,哈哈)。
如果实在不行,我就建议使用cvs下载了(客户不会不同意吧,这类后缀
名的文件,基本上默认就是用excel方式打开的,基本上不会有什么影响吧)
如果把应用程序部署到服务器上,由于服务器性能原因,基本上能够满
足客户需求,暂时没出现过内存溢出现象,所以我建议你去服务器上试试(
开大JVM内存也可以试试,悄悄的,不给他说,哈哈)。
如果实在不行,我就建议使用cvs下载了(客户不会不同意吧,这类后缀
名的文件,基本上默认就是用excel方式打开的,基本上不会有什么影响吧)
07的話,用流輸出模式
我用的是POI.采用POI的SXSSFWorkbook对象,如:
SXSSFWorkbook workbook = new SXSSFWorkbook(100);这个100就是缓存行数,就这样往Excel写,写个100万不是问题,速度也很快.如果是需要向一个现有的Excel文件再次写入数据,并且现有的Excel文件已经有很多数据了,如100万.
则直接向该文件写入还是会溢出,最好是每次都新写个Excel文件,然后再调用VB,执行2个Excel文件之间的sheet拷贝,这样是可以成功的
看完个位的回复很有心得,最后想到每写完一行数据就从list中移除这条数据。
这样就解决了内存不足的情况,大家可以试试~~