在Servlet端生成带有Excel表格的内存zip文件

这里基本上我试图发送Excel文件从服务器到客户端的zip文件。

方法1:我的Servlet代码

ByteArrayOutputStream bos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(bos); for(Map.Entry<String, List<Data>> entry : DatasMap.entrySet()) { String fileName = entry.getKey(); List<Data> excelData = entry.getValue(); // The below code constructs the workbook and returns it SXSSFWorkbook workBook = getWorkBook(fileName, excelData); ZipEntry zipEntry = new ZipEntry(fileName ); zos.putNextEntry(zipEntry); workBook.write(zos); zos.closeEntry(); // getting error at this line } 

错误:

 SEVERE: Servlet.service() for servlet [MyApp-server] in context with path [/myapp-server] threw exception java.io.IOException: Stream closed at java.util.zip.ZipOutputStream.ensureOpen(ZipOutputStream.java:82) at java.util.zip.ZipOutputStream.closeEntry(ZipOutputStream.java:231) 

方法2:

 ByteArrayOutputStream bos = new ByteArrayOutputStream(); ZipOutputStream zos = new ZipOutputStream(bos); ServletOutputStream out = response.getOutputStream(); for(Map.Entry<String, List<Data>> entry : DatasMap.entrySet()) { String fileName = entry.getKey(); List<Data> excelData = entry.getValue(); // The below code constructs the workbook and returns it SXSSFWorkbook workBook = getWorkBook(fileName, excelData); ZipEntry zipEntry = new ZipEntry(fileName ); zos.putNextEntry(zipEntry); workBook.write(bos); bos.writeTo(zos) zos.closeEntry(); // this line works perfectly in this case } zos.close(); byte[] bytes = bos.toByteArray(); //setting content-type and zip file name response.setContentType("application/zip"); response.setHeader("Content-Disposition", "attachment; filename=Templates.zip"); out.write(bytes); out.flush(); 

方法2工作正常,但是当我尝试在客户端打开zip文件时,我得到错误提示error extracting

在这里输入图像说明

我不知道是否excel sheet损坏或任何其他服务器端stream问题。 如果任何机构有一些有用的想法/想法,请与我分享。

您的第二次尝试失败,因为您通过直接将工作簿写入底层ByteArrayOutputStream来混合压缩的内容和解压缩的内容。 因此,生成的zip文件被搞砸了。

第一次尝试失败,因为workBook.writeclosures了ZipOutputStream ,当您写入第二个条目时,您将得到Stream closedexception。

但是你可以阻止这个stream的closures。 创build一个无法closures的助手OutputStream类:

 public class NonCloseableOutputStream extends java.io.FilterOutputStream { public NonCloseableOutputStream(OutputStream out) { super(out); } @Override public void close() throws IOException { flush(); } } 

并将该类的一个实例传递给工作簿:

 // The below code constructs the workbook and returns it SXSSFWorkbook workBook = getWorkBook(fileName, excelData); ZipEntry zipEntry = new ZipEntry(fileName ); zos.putNextEntry(zipEntry); workBook.write(new NonCloseableOutputStream(zos)); zos.closeEntry();