在 Servlet 端使用 excel 张生成内存中的 zip 文件
Generating in-memory zip file with excel sheets at Servlet side
基本上我是想从服务器向客户端发送带有 excel 张的 zip 文件。
方法一:我的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)
方法二:
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
是否损坏或任何其他服务器端流问题。如果有人有帮助 thoughts/ideas 请与我分享。
您的第二次尝试失败,因为您通过直接将工作簿写入底层 ByteArrayOutputStream
来混合压缩内容和解压缩内容。因此生成的 zip 文件搞砸了。
第一次尝试失败,因为 workBook.write
关闭了 ZipOutputStream
并且当您写入第二个条目时出现 Stream closed
异常。
但是您可以阻止流的关闭。创建一个无法关闭的助手 OutputStream
class:
public class NonCloseableOutputStream extends java.io.FilterOutputStream {
public NonCloseableOutputStream(OutputStream out) {
super(out);
}
@Override public void close() throws IOException {
flush();
}
}
并将 class 的实例传递给工作簿:
// 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();
基本上我是想从服务器向客户端发送带有 excel 张的 zip 文件。
方法一:我的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)
方法二:
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
是否损坏或任何其他服务器端流问题。如果有人有帮助 thoughts/ideas 请与我分享。
您的第二次尝试失败,因为您通过直接将工作簿写入底层 ByteArrayOutputStream
来混合压缩内容和解压缩内容。因此生成的 zip 文件搞砸了。
第一次尝试失败,因为 workBook.write
关闭了 ZipOutputStream
并且当您写入第二个条目时出现 Stream closed
异常。
但是您可以阻止流的关闭。创建一个无法关闭的助手 OutputStream
class:
public class NonCloseableOutputStream extends java.io.FilterOutputStream {
public NonCloseableOutputStream(OutputStream out) {
super(out);
}
@Override public void close() throws IOException {
flush();
}
}
并将 class 的实例传递给工作簿:
// 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();