写入两次输出流时POI损坏的文件

时间:2015-01-02 13:26:47

标签: 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保存到文件系统。然后附件保持正常并正常打开但文件系统上的文件已损坏

  3. 那是当我两次写同一个工作簿时,它会破坏第二次写入。

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

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

    目前我使用了一种解决方法,在将其写入文件

    后重新加载相同的excel文件
         workBook = new XSSFWorkbook(new FileInputStream(metricFile));
    

1 个答案:

答案 0 :(得分:2)

根据你的描述,这听起来像是一个最近也咬我的POI-bug,即this one。它在POI 3.11-beta1和21.12.2014中得到修复,已经发布了稳定的3.11版POI。所以我认为你最好的策略是升级你的POI版本,而不是试图产生一些黑客来解决这个问题。