1

I have some trouble with writing poi HSSFWorkBook data to ByteArrayOutputStream. Exception occuring when workbook more then 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 heap space at java.util.Arrays.copyOf(Arrays.java:2786) at java.io.ByteArrayOutputStream.write(ByteArrayOutputStream.java:94) at java.io.OutputStream.write(OutputStream.java:58) at org.apache.poi.poifs.storage.BigBlock.doWriteData(BigBlock.java:55) at org.apache.poi.poifs.storage.BATBlock.writeData(BATBlock.java:227) at org.apache.poi.poifs.storage.BigBlock.writeBlocks(BigBlock.java:86) at org.apache.poi.poifs.storage.BATBlock.writeBlocks(BATBlock.java:35) at org.apache.poi.poifs.storage.BlockAllocationTableWriter.writeBlocks(BlockAllocationTableWriter.java:151) at org.apache.poi.poifs.filesystem.POIFSFileSystem.writeFilesystem(POIFSFileSystem.java:398) at 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() at net.sf.cglib.proxy.MethodProxy.invoke(MethodProxy.java:191) at org.springframework.aop.framework.Cglib2AopProxy$CglibMethodInvocation.invokeJoinpoint(Cglib2AopProxy.java:689) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150) at org.springframework.aop.support.DelegatingIntroductionInterceptor.doProceed(DelegatingIntroductionInterceptor.java:131) at org.springframework.aop.support.DelegatingIntroductionInterceptor.invoke(DelegatingIntroductionInterceptor.java:119) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172) at 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) at java.lang.reflect.Method.invoke(Method.java:597) at 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) at org.springframework.faces.webflow.FlowActionListener.processAction(FlowActionListener.java:81) Aug 12, 2014 5:49:50 PM org.apache.catalina.core.StandardHostValve throwable WARNING: Exception Processing ErrorPage[exceptionType=java.lang.Throwable, location=/error/internalServerError.jsf] ClientAbortException: java.net.SocketException: Software caused connection abort: socket write error at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:330) at org.apache.catalina.connector.OutputBuffer.flush(OutputBuffer.java:296) at org.apache.catalina.connector.Response.flushBuffer(Response.java:549) at org.apache.catalina.core.StandardHostValve.throwable(StandardHostValve.java:272) at org.apache.catalina.core.StandardHostValve.invoke(StandardHostValve.java:141) at org.apache.catalina.valves.ErrorReportValve.invoke(ErrorReportValve.java:103) at org.apache.catalina.core.StandardEngineValve.invoke(StandardEngineValve.java:109) at org.apache.catalina.connector.CoyoteAdapter.service(CoyoteAdapter.java:293) at org.apache.coyote.http11.Http11Processor.process(Http11Processor.java:861) at org.apache.coyote.http11.Http11Protocol$Http11ConnectionHandler.process(Http11Protocol.java:606) at org.apache.tomcat.util.net.JIoEndpoint$Worker.run(JIoEndpoint.java:489) at java.lang.Thread.run(Thread.java:662) Caused by: java.net.SocketException: Software caused connection abort: socket write error at java.net.SocketOutputStream.socketWrite0(Native Method) at java.net.SocketOutputStream.socketWrite(SocketOutputStream.java:92) at java.net.SocketOutputStream.write(SocketOutputStream.java:136) at org.apache.coyote.http11.InternalOutputBuffer.realWriteBytes(InternalOutputBuffer.java:761) at org.apache.tomcat.util.buf.ByteChunk.flushBuffer(ByteChunk.java:448) at org.apache.coyote.http11.InternalOutputBuffer.flush(InternalOutputBuffer.java:318) at org.apache.coyote.http11.Http11Processor.action(Http11Processor.java:987) at org.apache.coyote.Response.action(Response.java:186) at org.apache.catalina.connector.OutputBuffer.doFlush(OutputBuffer.java:325) ... 11 more

Aventes
  • 569
  • 1
  • 8
  • 20
  • What is an `ExcelWorkBook`, and why are you constructing it from a byte array? The simple answer is "don't". Construct it from `currentWB`, and use that to write it out wherever you're ultimately writing it out to. Don't try to load entire files into memory, especially twice like this. – user207421 Aug 13 '14 at 07:41

1 Answers1

1

I'm currently using the same lib and never had to deal with such big files (10MB). As far as I know the only limits here are with > 65K rows and > 1 million columns for XLSX. Also be careful when you use Writer, because this operation is relatively slow. The OutOfMemoryError can be caused not only from the usage of the POI lib.

Update:

I'm currently working with newer XLSX format (I don't know if that matters) and use it like this:

`

FileOutputStream fileOutputStream = new FileOutputStream(file)) { 
 workbook.write(fileOutputStream); 
 fileOutputStream.flush();
 fileOutputStream.close(); }

`

I also use:

File file = new File(relativePath);

Please note that there is .flush() before .close()

ekostadinov
  • 6,880
  • 3
  • 29
  • 47