我目前在 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)
但我对这种行为的原因很感兴趣。 我希望当原始文件附加到问题时,内存中的表示不会影响原始文件。 谢谢您的任何见解。
从文件打开 XSSFWorkbook 比从 InputStream 打开内存占用更低
它没有直接回答您的问题,但它让您知道文件实际上用作内存缓冲区。
我认为你可以使用输入流而不是创建文件副本
注意:使用 InputStream 比使用 File 需要更多内存
new File("path/Template.xlsx").withInputStream{ stream->
def wb = new XSSFWorkbook(stream)
...rest of your code here...
}