为什么使用XSSFWorkbook会修改原始文件?

问题描述 投票:0回答:1

我目前在 Jira Scriptrunner 中使用 Groovy。我正在使用 apache 的 XSSFWorkbook。 在脚本中,我加载一个“模板”.xslx 文件,然后使用脚本对其进行修改。虽然文件从未以相同的文件名保存到服务器,但仅调用

workbook.write(outputStream)
workbook.close()
,服务器上的原始文件已被修改。

这是代码:

import org.apache.poi.xssf.usermodel.XSSFWorkbook
import releasemanagement.changes.AttachmentCreator
import other.TMPConfig
import com.atlassian.jira.issue.fields.CustomField
import com.atlassian.jira.issue.CustomFieldManager
import com.atlassian.jira.component.ComponentAccessor
import org.apache.poi.xssf.usermodel.XSSFCell

CustomFieldManager custFldManag = ComponentAccessor.getCustomFieldManager()

def issue = Issues.getByKey("ISSUEKEY")

def attachmentCreator = new AttachmentCreator()
def attachmentManager = ComponentAccessor.getAttachmentManager()

def wb = new XSSFWorkbook(new File("path/Template.xlsx"))

CustomField currCF
XSSFCell currCell
String reportType = "Initial"

TMPConfig.fieldToCell.each{k, v ->
    List<Integer> cellCoordinates = v.get(reportType)
    if(cellCoordinates){
        currCell = wb.getSheetAt(cellCoordinates[0]).getRow(cellCoordinates[1]).getCell(cellCoordinates[2])
        if(currCell){
            currCF = custFldManag.getCustomFieldObject(k)
            currCell.setCellValue(currCF.getValue(issue).toString())
        }
    }
}

ByteArrayOutputStream out = new ByteArrayOutputStream()
wb.write(out)
wb.close()
ByteArrayInputStream inputStream = new ByteArrayInputStream(out.toByteArray())
out.close()

int filename_num = 1
String filename = "Dora_${reportType}_${filename_num}.xlsx"

attachmentCreator.createAttachmentForIssue(issue, filename, "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", inputStream)

目前,我的同事通过解决方法解决了这个问题:

XSSFWorkbook wb_temp = new XSSFWorkbook(new File("path/Template.xlsx"))
    ByteArrayOutputStream out_temp = new ByteArrayOutputStream()
        wb_temp.write(out_temp)
        wb_temp.close()
    ByteArrayInputStream inputStream_temp = new ByteArrayInputStream(out_temp.toByteArray())
        out_temp.close()
    XSSFWorkbook wb = new XSSFWorkbook(inputStream_temp)

但我对这种行为的原因很感兴趣。 我希望当原始文件附加到问题时,内存中的表示不会影响原始文件。 谢谢您的任何见解。

groovy jira scriptrunner-for-jira
1个回答
0
投票

https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFWorkbook.html#XSSFWorkbook-java.io.File-

从文件打开 XSSFWorkbook 比从 InputStream 打开内存占用更低

它没有直接回答您的问题,但它让您知道文件实际上用作内存缓冲区。


我认为你可以使用输入流而不是创建文件副本

https://poi.apache.org/apidocs/dev/org/apache/poi/xssf/usermodel/XSSFWorkbook.html#XSSFWorkbook-java.io.InputStream-

注意:使用 InputStream 比使用 File 需要更多内存

new File("path/Template.xlsx").withInputStream{ stream->
  def wb = new XSSFWorkbook(stream)
  ...rest of your code here...
}
© www.soinside.com 2019 - 2024. All rights reserved.