我现在也遇到这个问题了。我想将此 XSSFWorkbook(工作簿)obj 中的 excel 文件写入 zip 文件,例如(example.zip,同时包含此 example.xlsx 文件)到远程服务器。 我尝试过以下操作但不起作用,它创建了一个文件夹,其中 zip 文件中有一些奇怪的文件
XSSFWorkbook workbook = new XSSFWorkbook();
//add some data
Zipoutputstream zipstream=new Zipoutputstream(//destination outputstream);
workbook.write(zipstream);
那么有谁知道这样做的正确方法是什么?预先感谢
ps workbook.write(fileoutputstream) 可以工作,但它只作为平面文件(例如 test.xlsx)写入本地磁盘,而不是根据我需要写入 zip 中。
将
ZipOutputStream
传递给 XSSFWorkbook.write
将导致流被工作簿劫持并关闭。这是因为 XSSFWorkbook
写入了 .xlsx
,它本身就是 xml 和其他文件的 zip 存档(您可以解压缩任何 .xslx 以查看其中的内容)。
如果您能够将 excel 文件放入内存中,我发现它效果很好:
ZipOutputStream zos = new ZipOutputStream(//destination outputstream);
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx"));
ByteArrayOutputStream bos = new ByteArrayOutputStream();
workbook.write(bos);
bos.writeTo(zos);
zos.closeEntry();
// Add other entries as needed
zos.close();
在
close
上调用 ByteArrayOutputStream
没有任何效果,仍然可以写入 zos
。
您的
ZipOutputStream
错过了一些必要的电话。您需要为电子表格文件创建一个 ZipEntry
,然后将其写出来。你需要类似的东西
zipstream.putNextEntry(new ZipEntry("example.xlsx"));
那么你应该可以打电话
workbook.write(zipstream);
但是之后您需要在关闭流之前关闭条目。
zipstream.closeEntry();
请参阅 “从 Java 写入和读取 .Zip 文件”,了解如何使用 Java 的
ZipOutputStream
的详细信息。
另外,请注意 .xlsx 文件已经是压缩的 zip 文件,因此将其放入 .zip 文件中可能不会压缩太多。
我的一位同事 M. Bunshaft 提出了一种与 Klugscheißer 类似的解决方案,但不需要使用 ByteArrayOutputStream,因此可以容纳更大的输出。 这个想法是子类 ZipOutputStream,重写 close() 方法,这样它就不会执行关闭。
public class UncloseableZipOutputStream extends ZipOutputStream
{
OutputStream os;
public UncloseableZipOutputStream( OutputStream os )
{
super(os);
}
@Override
/** just flush but do not close */
public void close() throws IOException
{
flush();
}
public void reallyClose() throws IOException
{
super.close();
}
}
然后,只需按照使用 ZipOutputStream 的方式使用它即可。
UncloseableZipOutputStream zos = new UncloseableZipOutputStream(//destination outputstream);
zos.putNextEntry(new ZipEntry("AnExcelFile.xlsx"));
workbook.write(zos);
zos.closeEntry(); // now this will not cause a close of the stream
// Add other entries as needed
zos.reallyClose();
这个方法对我有用: (输入是您拥有的文件的 byteArray)
public static byte[] zipBytes(String filename, byte[] input) throws IOException {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
ZipOutputStream zos = new ZipOutputStream(baos);
ZipEntry entry = new ZipEntry(filename);
entry.setSize(input.length);
zos.putNextEntry(entry);
zos.write(input);
zos.closeEntry();
zos.close();
return baos.toByteArray();
}