java - POI 向输出流写入两次时损坏文件

标签 java apache-poi

我的要求是创建一个工作簿对象,然后将 xlsx 文件保存到文件系统,然后将相同的工作簿对象作为电子邮件附件发送。

我做了什么:

创建工作簿对象:

XSSFWorkbook workBook = excelGenerator.createWorkBook(output);
 saveToFile(input, workBook);
 mailSender.sendNotificationWithAttachment(input, excelGenerator.saveToByteArray(workBook), emailId);

其中 saveToFile():

File metricFile = new File(metricsDirectory, filename + ".xlsx");
 try{
     FileOutputStream fileOut =new FileOutputStream(metricFile);
     workBook.write(fileOut);
     fileOut.flush();
     fileOut.close();
 }

saveToByteArray():

 ByteArrayOutputStream byteOutputStream = new ByteArrayOutputStream();
 try {
     workBook.write(byteOutputStream);
 } catch (IOException e) {
 }
 return byteOutputStream;
  1. 如果我首先将流写入文件,然后将 byteArrayOutputStream 作为附件发送,则附件已损坏,当我打开时,它会警告我文件已损坏,如果我说“确定”,它会正确打开文件。生成的文件完全没问题。

  2. 如果我先发送附件,然后将 Excel 保存到文件系统。然后附件保持正常并正常打开,但文件系统上的文件已损坏

也就是说,当我两次写入同一工作簿时,它会损坏第二次写入。

我还尝试将不同的工作簿对象传递给这两个步骤,在这种情况下它可以正常工作。

我正在寻找一种解决方案,可以在写入另一个 Excel 之前将 XSSFWorkbook 对象或其内容复制到单独的对象。

目前,我使用一种解决方法在将同一 Excel 文件写入文件后重新加载该文件

     workBook = new XSSFWorkbook(new FileInputStream(metricFile));

最佳答案

从你的描述来看,这听起来确实像是一个最近也咬过我的 POI-bug,即 this one 。它在 POI 3.11-beta1 中得到修复,并于 2014 年 12 月 21 日发布了稳定的 POI 3.11 版本。所以我认为你最好的策略是升级你的 POI 版本,而不是试图产生一些 hack 来解决这个问题。

关于java - POI 向输出流写入两次时损坏文件,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27742968/

相关文章:

java - 如何在 JNA 中传递包含原始类型数组的结构?

java - 使用 java 分析线程转储

java - 如何将excel数据读入 vector 表

java - 如何使用 Selenium 和 POI 从 Excel 的第一行迭代并尝试登录,然后再次迭代到第二行并尝试再次登录?

java - 在java中调用方法(包括Selenium/Apache-POI)

java - 如何使用 Apache POI 设置漂亮的浮点值?

java - 如何解决 Java 错误 : package javax. 注释不可见,Java 版本 9

java - 设置缺少可执行 Jar 图标

java - 将对话框中的信息存储到文本文件 Java

java - 如何在 apache poi 3.6 中创建新行?