【问题标题】:COSStream has been closed and cannot be readCOSStream 已关闭,无法读取
【发布时间】:2021-04-19 19:48:35
【问题描述】:

我的项目中有下一个代码,有时它会落在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;
    }

【问题讨论】:

    标签: java pdfbox


    【解决方案1】:

    您使用来自模板文档的流(templatePDDocumentfontTemplatePdf)重新创建,并且在每次循环迭代中免费进行垃圾收集。因此,在您调用outPDDocument.save 之前,其中一些模板文档可能已被垃圾收集完成,从而导致您观察到的错误。

    如果您保留此基础架构,您可以通过将它们全部添加到某个集合并仅在调用 outPDDocument.save 后清除该集合来防止这些模板文档过早完成。

    或者,您可以切换到克隆模板页面并使用克隆而不是使用原始模板页面。

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2020-05-19
      • 2013-08-17
      • 2012-11-10
      • 1970-01-01
      • 2019-04-16
      • 1970-01-01
      • 2015-01-15
      • 1970-01-01
      相关资源
      最近更新 更多