I'm getting an exception while writing data into an SXSSFWorkbook file. I could do the same using XSSFWorkbook and it worked just fine.
java.io.IOException: Cannot write data, document seems to have been closed already
at org.apache.poi.ooxml.POIXMLDocument.write(POIXMLDocument.java:230)
at org.apache.poi.xssf.streaming.SXSSFWorkbook.write(SXSSFWorkbook.java:953)
at org.glassfish.jersey.message.internal.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:79)
at org.glassfish.jersey.message.internal.StreamingOutputProvider.writeTo(StreamingOutputProvider.java:61)
at org.glassfish.jersey.message.internal.WriterInterceptorExecutor$TerminalWriterInterceptor.invokeWriteTo(WriterInterceptorExecutor.java:266)
Here is my code.
public static Response createResponseUsingStreaming() throws IOException {
SXSSFWorkbook workbook = report.generateStreamingExcelReport(100);
StreamingOutput outputStream = workbook::write;
final String contentType = "application/vnd.ms-excel";
Response.ResponseBuilder responseBuilder = Response.ok(outputStream);
responseBuilder.header("Content-Disposition", "attachment; filename=test");
responseBuilder.header("Access-Control-Expose-Headers", "Content-Disposition");
responseBuilder.header("Content-Type", contentType);
Response response = responseBuilder.build();
if (null != workbook) {
workbook.dispose();
workbook.close();
}
return response;
}
public SXSSFWorkbook generateStreamingExcelReport(int rowAccessWindowSize) {
List<List<String>> rows = createRawData();
SXSSFWorkbook sxssfWorkbook = new SXSSFWorkbook(rowAccessWindowSize);
createExcelSummaryPage(sxssfWorkbook);
createExcelDetailPage(rows, sxssfWorkbook);
return sxssfWorkbook;
}
OPCPackage is set when creating a new SXSSFWorkbook, wondering where this is getting set to null.
public final void write(OutputStream stream) throws IOException {
OPCPackage p = getPackage();
if(p == null) {
throw new IOException("Cannot write data, document seems to have been closed already");
}
//force all children to commit their changes into the underlying OOXML Package
// TODO Shouldn't they be committing to the new one instead?
Set<PackagePart> context = new HashSet<>();
onSave(context);
context.clear();
//save extended and custom properties
getProperties().commit();
p.save(stream);
}
If you can work with
XSSFWorkbookyou should be able to work withSXSSFWorkbookusing yourXSSFWorkbook.Here is a simple working example: