14

我现在有这个问题。我想将此 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 而不是我需要的压缩包内。

4

3 回答 3

24

将aa 传递ZipOutputStreamXSSFWorkbook.write将导致流被工作簿劫持和关闭。这是因为 aXSSFWorkbook写入的 a.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写入.ByteArrayOutputStreamzos

于 2015-01-24T22:59:17.377 回答
4

您在ZipOutputStream. 您需要ZipEntry为电子表格文件创建一个,然后将其写出来。你需要类似的东西

zipstream.putNextEntry(new ZipEntry("example.xlsx"));

然后你应该可以打电话

workbook.write(zipstream);

但在那之后,您需要在关闭流之前关闭条目。

zipstream.closeEntry();

有关如何使用 Java 的 .Zip 文件的详细信息,请参阅“从 Java 写入和读取 .Zip 文件”ZipOutputStream

另外,请注意 .xlsx 文件已经是压缩的 zip 文件,因此将其放在 .zip 文件中可能不会压缩太多。

于 2013-05-23T18:25:07.193 回答
3

我的一位同事 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();

于 2016-12-12T18:42:59.097 回答