【问题标题】:How to open a PdfADocument from an existing PdfDocument in itext7?如何从 itext7 中的现有 PdfDocument 打开 PdfADocument?
【发布时间】:2019-05-28 21:30:31
【问题描述】:

为了检查上传的 PDF 文件的基本 PDF/A 一致性,我需要将它们作为 PdfADocuments 读取。 但从 7.1.6 版开始,这不再有效,而是抛出 PdfException(PdfException.PdfReaderHasBeenAlreadyUtilized)

class Controller
...
// get uploaded data into PdfDocument, which is passed
// on to different services.

InputStream filecontent = fileupload.getInputStream();
int read = 0;
byte[] bytes = new byte[1024];
ByteArrayOutputStream buffer = new ByteArrayOutputStream();
while ((read = filecontent.read(bytes,0,bytes.length)) != -1) {
    filesize += read;
    buffer.write(bytes, 0, read);
}

ByteArrayInputStream input = new ByteArrayInputStream(buffer.toByteArray());
PdfReader reader = new PdfReader(input); 
PdfWriter writer = new PdfWriter(new ByteArrayOutputStream());

PdfDocument pdf = new PdfDocument(reader, writer);

AnalyzerService analyzer = new AnalyzerService();
if(analyzer.analyze(pdf)) {
    otherService.doSomethingWith(pdf);
}
...

class AnalyzerService
...
public boolean analyze(PdfDocument pdf) {
    PdfADocument pdfa = new PdfADocument(
        pdf.getReader(), pdf.getWriter() <-- PdfException here
    );
...
}

直到并包括 iText 7.1.5 这都有效。

在 7.1.6 中,我收到“com.itextpdf.kernel.PdfException: Given PdfReader 实例已被使用。PdfReader 无法重复使用,请创建一个新实例。”

看来我需要从 PdfDocument 中获取字节作为字节 [],然后从中创建一个新的 PdfReader。我尝试从 pdf.getReader().getOutputStream().toByteArray() 中获取它们,但这不起作用。

目前我对如何从给定的 PdfDocument 创建 PdfADocument 感到很困惑。

【问题讨论】:

    标签: java itext itext7


    【解决方案1】:

    对于PdfDocumentPdfADocument 实例,您的方法使用相同的PdfReader 和(更糟糕的是)相同的PdfWriter。由于两者都可以操作PdfReader并写入PdfWriter,这种情况很可能导致writer中出现垃圾,所以你不要这样做。

    始终将包含阅读器和编写器的文档视为正在进行中的文档,不能将其视为已完成的文档文件,例如提取用于中间检查。

    当您想要检查上传的 PDF 文件时,为什么不简单地将 byte[]buffer.toByteArray() 转发到 analyze 方法以创建单独的阅读器(如果需要,是,一个文件)来自?这确实会检查上传的文件...

    此外,如果您的输入文档可能符合 PDF/A 标准并且在这种情况下被特殊处理,您是否也应该将其作为PdfADocument 进行处理? IE。您不应该首先检查分析器的一致性,并在肯定的情况下在控制器类中使用PdfADocument 吗?

    【讨论】:

    • 谢谢@mkl! PdfWriter 及其输出从未使用过,它之所以存在,是因为 PdfADocument 坚持拥有一个 ;-) 我更改了整个应用程序以将 PdfDocuments 视为临时的,并且仅在工作流中传递 byte[] 中的数据。但是,这相当乏味,并且每次重新创建 PdfDocument(new PdfReader(new ByteArrayInputStream(byteArray))) 都会导致明显的性能影响。还有其他更适合通过工作流传递的对象类型吗?
    • “从未使用过 PdfWriter 及其输出” - 那你为什么还要在那里呢?有一个 PdfDocument 构造函数,只有一个阅读器,没有编写器......可能在你的情况下使用该构造函数就足够了......
    • 正确。唯一的原因是 - 我通过工作流将 PdfDocument 作为一种持久对象传递(这似乎是一个坏主意 ;-) - 在该工作流的某处调用的 PdfADocument 构造函数想要它,我认为它不会从同一个 PdfReader 读取 PdfDocument 和 PdfADocument 很好,但使用不同的 PdfWriter 实例。
    • 但是根据您的帖子,整个概念似乎与这些对象的设计目的不一致,所以我将放弃这种方法。
    • 仍然想知道是否有一种方法可以在整个工作流程中使用更符合一般 iText 设计原则的单个对象。
    【解决方案2】:
            PdfDocument SourcePDF=null;
            PdfADocument DisPDF =null;
            try
            {
                PdfReader Reader = new PdfReader(input-Path);
                PdfWriter writer = new PdfWriter(output-Path, new WriterProperties().SetPdfVersion(PdfVersion.PDF_2_0));
                writer.SetSmartMode(true);
                SourcePDF = new PdfDocument(Reader);
                DisPDF = new PdfADocument(writer, PdfAConformanceLevel.PDF_A_3A,
                    new PdfOutputIntent("Custom", "", "https://www.color.org", "sRGB", new MemoryStream(Properties.Resources.sRGB_CS_profiles)));
                DisPDF.InitializeOutlines();
                //Setting some required parameters
                DisPDF.SetTagged();
                DisPDF.GetCatalog().SetLang(new PdfString("en-EN"));
                DisPDF.GetCatalog().SetViewerPreferences(new PdfViewerPreferences().SetDisplayDocTitle(true));
    
    
                PdfMerger merger = new PdfMerger(DisPDF, true, true);
                merger.Merge(SourcePDF, 1, sorsePDF.GetNumberOfPages());
                SourcePDF.Close();
                DisPDF.Close();
             }
             catch (Exception ex)
             {
                 throw;
             }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2018-10-08
      • 1970-01-01
      • 1970-01-01
      • 2021-11-26
      • 1970-01-01
      • 2020-10-23
      相关资源
      最近更新 更多