【问题标题】:Error when reading PDF file generated by MS Office读取 MS Office 生成的 PDF 文件时出错
【发布时间】:2020-02-26 01:58:19
【问题描述】:

每当我尝试阅读 Office 生成的 PDF 文件时,似乎都会出现错误:

com.itextpdf.kernel.PdfException: Append mode requires a document without errors, even if recovery is possible.
    at com.itextpdf.kernel.pdf.PdfDocument.open

有问题的文件示例:https://drive.google.com/open?id=1fnwtXfEGg6BIeVuAi-l28Ol_dxbCd12F 和我用来打开它的代码片段。我的目标是做一个分离的签名,只要不是由 MS Office 生成的,这对每个文件都适用。

PdfReader reader = new PdfReader(docPath);
StampingProperties properties = new StampingProperties();
        properties.useAppendMode();

//This is where the error is thrown.
PdfSigner signer = new PdfSigner(reader, new FileOutputStream(outputPath), properties);

我读过这个基本上是相同问题的问题:Append mode requires a document without errors, even if recovery is possible,尝试了 Lowagie 建议的删除字节

xref
0 24
0000000000 65535 f 
0000011981 00000 n 
0000000239 00000 n 
0000003212 00000 n 
0000000022 00000 n 
0000000220 00000 n 
0000000343 00000 n 
0000003176 00000 n 
0000000000 00000 n 
0000003345 00000 n 
0000000440 00000 n 
0000003155 00000 n 
0000003295 00000 n 
0000003863 00000 n 
0000003519 00000 n 
0000003843 00000 n 
0000004099 00000 n 
0000011737 00000 n 
0000011758 00000 n 
0000011803 00000 n 
0000011877 00000 n 
0000011900 00000 n 
0000011942 00000 n 
0000011961 00000 n 
trailer
<< /Size 24 /Root 12 0 R /Info 1 0 R /ID [ <8e4b8658dd1d1f745bdf99a0eb05bb97>
<8e4b8658dd1d1f745bdf99a0eb05bb97> ] >>
startxref
12125
%%EOF

但我的 PDF 抱怨并停止工作,也尝试离开 %%EOF 但得到了相同的结果。

所以两件事:

1) Lowagie 和 MKL 讨论的错误是否有修复?

2) 有什么办法可以解决这个问题?

【问题讨论】:

  • 你真的需要追加模式吗?如果该文档尚不包含任何签名,那么对我而言,您为什么需要使用它并不明显。你能详细说明一下吗?

标签: pdf itext ms-office itext7


【解决方案1】:

首先,question you refer to不是关于基本上是同一个问题,你只是得到同样的错误信息。有问题的 PDF 有一个混合参考 PDF,而您的文件不是:您的文件只有一个交叉参考表和一个预告片,而混合参考 PDF 有(至少)两个交叉参考表,每个表后跟一个预告片,并且后一个预告片有一个指向交叉引用流的 XRefStm 条目。混合参考 PDF 是有效的,iText 7 曾经遇到过此类 PDF 的问题,这是一个错误。

另一方面,您的 PDF 文件本身实际上有一个错误:交叉引用表声称对象 8 位于文件偏移量 0 处

xref
0 24
...
0000000000 00000 n 

这是不可能的,因为在文件的开头有 PDF 标题。此外,随后出现的第一个对象是对象 4,因此也不能说偏移后的第一个对象是指...

iText 7 仅在未在源文件中发现问题时才允许附加模式。这是合理的。

因此,如果您以可重现的方式遇到该错误,您应该向 PDF 制作者提交错误。

您声称 PDF 文件由 MS Office 生成的。另一方面,PDF 的元数据表明,虽然 MS Word 是 文档的创建者,但实际的PDF 的生产者 是 Quartz PDFContext。您可能想为 Quartz PDFContext 提交问题。

您的解决方法是捕获此异常并在不使用附加模式的情况下重试。

或者,如果您真的真的需要以附加模式处理这些损坏的文件,您可以通过使用始终返回的方法覆盖 hasRebuiltXref 来使 PdfReader 谎报发现的错误false,例如通过替换

PdfReader reader = new PdfReader(SOURCE);

通过

PdfReader reader = new PdfReader(SOURCE) {
    @Override
    public boolean hasRebuiltXref() {
        return false;
    }
};

(StampNoChange 测试testAppendTest)

但请注意,结果 PDF 仍包含原始文件中标识的错误 iText。因此,任何进一步处理您的 PDF 的 PDF 处理器也可能会绊倒,或者与 iText 最初的方式相同,或者以其他一些可能非常壮观的方式。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2018-06-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多