将poi HSSFWorkBook数据写入ByteArrayOutputStream时遇到了一些麻烦。当工作簿超过10MB时发生异常。
private Workbook currentWB;
public DataSource getDataSource() throws Exception {
ByteArrayOutputStream out = new ByteArrayOutputStream();
try {
**currentWB.write(out); <-Exception occurs in this line, when workbook writing in outputstream**
} finally {
out.close();
}
return new XLSDataSource (TEMPLATE_FILE_NAME, out.toByteArray());
}
private static class XLSDataSource implements DataSource {
private final String name;
private final byte[] content;
private XLSDataSource(String name, byte[] content) {
super();
this.name = name;
this.content = content;
}
@Override
public String getContentType() {
return "application/vnd.ms-excel";
}
@Override
public InputStream getInputStream() throws IOException {
return new ByteArrayInputStream(content);
}
@Override
public String getName() {
return name;
}
@Override
public OutputStream getOutputStream() throws IOException {
throw new UnsupportedOperationException();
}
}
StackTrace:
java.lang.OutOfMemoryError:Java堆空间 at java.util.Arrays.copyOf(Arrays.java:2786) at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94) 在java.io.OutputStream.write(OutputStream.java:58) 在org.apache.poi.poifs.storage.BigBlock.doWriteData(BigBlock.java:55) 在org.apache.poi.poifs.storage.BATBlock.writeData(BATBlock.java:227) 在org.apache.poi.poifs.storage.BigBlock.writeBlocks(BigBlock.java:86) 在org.apache.poi.poifs.storage.BATBlock.writeBlocks(BATBlock.java:35) 在org.apache.poi.poifs.storage.BlockAllocationTableWriter.writeBlocks(BlockAllocationTableWriter.java:151) 在org.apache.poi.poifs.filesystem.POIFSFileSystem.writeFilesystem(POIFSFileSystem.java:398) 在org.apache.poi.hssf.usermodel.HSSFWorkbook.write(HSSFWorkbook.java:1181) at uk.co.itrainconsulting.appbook.core.impl.service.exportBusinessData.XLSRenderer.getDataSource(XLSRenderer.java:79) at uk.co.itrainconsulting.appbook.core.impl.service.BusinessExportDataServiceImpl.getDataSource(BusinessExportDataServiceImpl.java:119) at uk.co.itrainconsulting.appbook.core.impl.service.BusinessExportDataServiceImpl.sendByEmail(BusinessExportDataServiceImpl.java:75) at uk.co.itrainconsulting.appbook.web.bean.BusinessExportDataBean.sendBusinessData(BusinessExportDataBean.java:71) at uk.co.itrainconsulting.appbook.web.bean.BusinessExportDataBean $$ FastClassByCGLIB $$ 307f293f.invoke() 在net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) 在org.springframework.aop.framework.Cglib2AopProxy $ CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) 在org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131) 在org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119) 在org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) 在org.springframework.aop.framework.Cglib2AopProxy $ DynamicAdvisedInterceptor.intercept(Cglib2AopProxy.java:622) at uk.co.itrainconsulting.appbook.web.bean.BusinessExportDataBean $$ EnhancerByCGLIB $$ 1bb626b3.sendBusinessData() at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39) at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25) 在java.lang.reflect.Method.invoke(Method.java:597) 在com.sun.el.parser.AstValue.invoke(AstValue.java:234) at com.sun.el.MethodExpressionImpl.invoke(MethodExpressionImpl.java:297) at com.sun.faces.facelets.el.TagMethodExpression.invoke(TagMethodExpression.java:102) at javax.faces.component.MethodBindingMethodExpressionAdapter.invoke(MethodBindingMethodExpressionAdapter.java:84) 在org.springframework.faces.webflow.FlowActionListener.processAction(FlowActionListener.java:81) 2014年8月12日下午5:49:50 org.apache.catalina.core.StandardHostValve throwable 警告:异常处理ErrorPage [exceptionType = java.lang.Throwable,location = / error / internalServerError.jsf] ClientAbortException:java.net.SocketException:软件导致连接中止:套接字写入错误 在org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:330) 在org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:296) 在org.apache.catalina.connector.Response.flushBuffer(Response.java:549) 在org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:272) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) 在org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) 在org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) 在org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) 在org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861) 在org.apache.coyote.http11.Http11Protocol $ Http11ConnectionHandler.process(Http11Protocol.java:606) 在org.apache.tomcat.util.net.JIoEndpoint $ Worker.run(JIoEndpoint.java:489) 在java.lang.Thread.run(Thread.java:662) 引起:java.net.SocketException:软件导致连接中止:套接字写入错误 at java.net.SocketOutputStream.socketWrite0(Native Method) 在java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) 在java.net.SocketOutputStream.write(SocketOutputStream.java:136) 在org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:761) 在org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:448) 在org.apache.coyote.http11.InternalOutputBuffer.flush(InternalOutputBuffer.java:318) 在org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:987) 在org.apache.coyote.Response.action(Response.java:186) 在org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:325) ......还有11个
答案 0 :(得分:0)
我目前正在使用相同的lib,从来没有处理过这么大的文件(10MB)。据我所知,这里唯一的限制是&gt; 65K行和> XLSX的100万列。使用Writer时也要小心,因为此操作相对较慢。 OutOfMemoryError不仅可以由POI lib的使用引起。
更新
我目前正在使用更新的XLSX格式(我不知道这是否重要)并使用它如下:
`
FileOutputStream fileOutputStream = new FileOutputStream(file)) {
workbook.write(fileOutputStream);
fileOutputStream.flush();
fileOutputStream.close(); }
`
我也用:
File file = new File(relativePath);
请注意.close()
之前有.flush()