OutOfMemoryError:将poi.WorkBook写入ByteArrayOutputStream时的Java堆空间

时间:2014-08-13 06:17:47

标签: java excel apache-poi

将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个

1 个答案:

答案 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()