COSStream 已经关闭,无法读取
COSStream has been closed and cannot be read
我的项目中有下一个代码,它有时会落在 COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
它发生在不同的时间和不同的工作量,所以我想修复它。
提前致谢。
public void transferBankActPagesToPdfFile(List<PdfBankActPage> acts, HttpServletResponse response)
throws IOException {
try (PDDocument outPDDocument = new PDDocument()) {
for (PdfBankActPage pdfBankActPage : acts) {
String templateFilename = TEMPLATES_FOLDER + DELIMETER + pdfBankActPage.getPdfTemplateName();
PDDocument templatePDDocument = PDDocument.load(readResource(templateFilename));
PDPage pdPage = templatePDDocument.getPage(0);
String fontTemplatePath = TEMPLATES_FOLDER + DELIMETER + FONT_TEMPLATE;
PDDocument fontTemplatePdf = PDDocument.load(readResource(fontTemplatePath));
PDPage fontTemplatePage = fontTemplatePdf.getPage(0);
PDResources fontTemplateResources = fontTemplatePage.getResources();
PDFont cyrillicFont = null;
for (COSName cosName : fontTemplateResources.getFontNames()) {
if (cosName.getName().equals("F4")) {
cyrillicFont = fontTemplateResources.getFont(cosName);
}
}
outPDDocument.addPage(pdPage);
PDPageContentStream contentStream = new PDPageContentStream(templatePDDocument, pdPage,
PDPageContentStream.AppendMode.APPEND, true, true);
List<PdfTextLine> textLines = pdfBankActPage.getTextLines();
if (textLines != null) {
for (PdfTextLine textLine : textLines) {
contentStream.setFont(cyrillicFont, textLine.getFontSize());
contentStream.beginText();
contentStream.newLineAtOffset(textLine.getOffsetX(), textLine.getOffsetY());
contentStream.showText(textLine.getText());
contentStream.endText();
}
}
contentStream.close();
}
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
outPDDocument.save(response.getOutputStream());
}
}
这里是加载资源的部分:
private InputStream readResource(String resourceFilename) {
InputStream inputStream = PdfBankActPagesToPdfFile.class.getResourceAsStream(resourceFilename);
if (inputStream == null) {
inputStream = PdfBankActPagesToPdfFile.class.getClassLoader().getResourceAsStream(resourceFilename);
}
return inputStream;
}
您使用来自模板文档(templatePDDocument
、fontTemplatePdf
)的流,这些流是重新创建的,并且在每次循环迭代中都免费用于垃圾收集。因此,其中一些模板文档可能在您调用 outPDDocument.save
之前已通过垃圾回收完成,从而导致您观察到的错误。
如果您保留此基础架构,您可以通过将它们全部添加到某个集合并仅在调用 outPDDocument.save
后清除该集合来防止这些模板文档过早完成。
或者,您可以切换到克隆模板页面并使用克隆而不是使用原始模板页面。
我的项目中有下一个代码,它有时会落在 COSStream has been closed and cannot be read. Perhaps its enclosing PDDocument has been closed?
它发生在不同的时间和不同的工作量,所以我想修复它。
提前致谢。
public void transferBankActPagesToPdfFile(List<PdfBankActPage> acts, HttpServletResponse response)
throws IOException {
try (PDDocument outPDDocument = new PDDocument()) {
for (PdfBankActPage pdfBankActPage : acts) {
String templateFilename = TEMPLATES_FOLDER + DELIMETER + pdfBankActPage.getPdfTemplateName();
PDDocument templatePDDocument = PDDocument.load(readResource(templateFilename));
PDPage pdPage = templatePDDocument.getPage(0);
String fontTemplatePath = TEMPLATES_FOLDER + DELIMETER + FONT_TEMPLATE;
PDDocument fontTemplatePdf = PDDocument.load(readResource(fontTemplatePath));
PDPage fontTemplatePage = fontTemplatePdf.getPage(0);
PDResources fontTemplateResources = fontTemplatePage.getResources();
PDFont cyrillicFont = null;
for (COSName cosName : fontTemplateResources.getFontNames()) {
if (cosName.getName().equals("F4")) {
cyrillicFont = fontTemplateResources.getFont(cosName);
}
}
outPDDocument.addPage(pdPage);
PDPageContentStream contentStream = new PDPageContentStream(templatePDDocument, pdPage,
PDPageContentStream.AppendMode.APPEND, true, true);
List<PdfTextLine> textLines = pdfBankActPage.getTextLines();
if (textLines != null) {
for (PdfTextLine textLine : textLines) {
contentStream.setFont(cyrillicFont, textLine.getFontSize());
contentStream.beginText();
contentStream.newLineAtOffset(textLine.getOffsetX(), textLine.getOffsetY());
contentStream.showText(textLine.getText());
contentStream.endText();
}
}
contentStream.close();
}
response.setContentType(MediaType.APPLICATION_PDF_VALUE);
outPDDocument.save(response.getOutputStream());
}
}
这里是加载资源的部分:
private InputStream readResource(String resourceFilename) {
InputStream inputStream = PdfBankActPagesToPdfFile.class.getResourceAsStream(resourceFilename);
if (inputStream == null) {
inputStream = PdfBankActPagesToPdfFile.class.getClassLoader().getResourceAsStream(resourceFilename);
}
return inputStream;
}
您使用来自模板文档(templatePDDocument
、fontTemplatePdf
)的流,这些流是重新创建的,并且在每次循环迭代中都免费用于垃圾收集。因此,其中一些模板文档可能在您调用 outPDDocument.save
之前已通过垃圾回收完成,从而导致您观察到的错误。
如果您保留此基础架构,您可以通过将它们全部添加到某个集合并仅在调用 outPDDocument.save
后清除该集合来防止这些模板文档过早完成。
或者,您可以切换到克隆模板页面并使用克隆而不是使用原始模板页面。