【问题标题】:Itext7 cleanup method throws error - Index was out of rangeItext7 清理方法抛出错误 - 索引超出范围
【发布时间】:2021-03-10 09:26:21
【问题描述】:

我在尝试使用 itext7 编辑 pdf 文档时遇到以下错误

我正在调用 pdfCleanupTool.cleanup() 方法进行编辑,有时我会从清理方法中收到以下错误:

索引超出范围。必须为非负数且小于集合的大小。\r\n参数名称:索引

任何帮助表示赞赏。 谢谢!

更新:

错误日志:

【问题讨论】:

  • 请分享一个示例 pdf 以重现该问题。
  • @mkl 抱歉,这是一份客户文件。无法分享。但是,当我对特定文本应用编辑然后尝试使用 itext 应用时,就会出现问题。
  • 那么请尝试找到另一个您可以共享的文档,但清理失败同样如此。如果您找不到这样的文档,则手头的 PDF 中的错误很可能是导致错误的原因。您至少可以提供错误的完整堆栈跟踪。运气好的话,堆栈跟踪提示了问题的原因。
  • @mkl 按照您的建议更新了错误日志
  • 乍一看不应该发生的来源。你到底用的是哪个版本,可能已经修好了……

标签: pdf c#-4.0 itext itext7


【解决方案1】:

iText 7 PdfTextArray 类中存在一个错误,该错误会生成与您类似的堆栈跟踪。不过,由于您不共享您的 PDF,我无法确定这是否是目前困扰您的错误。

虫子

这个 bug 很容易在 Java 中引发,就像这样

PdfTextArray textArray = new PdfTextArray();
textArray.add(1);
textArray.add(-1);
textArray.add(1);

(CancelingAdjustments 测试testCancelingAdjustments)

在 C# 中也是如此。

这基本上可能是 OP 的情况;编校涉及从此类文本数组中删除文本片段并通过等效的数字调整进行替换,因此在编校期间这种情况可能比一般情况下更可能发生。

原因

将多个数字添加到PdfTextArray 时,它会尝试将它们组合成一个数字,如果该单个数字为零,则将其完全删除:

public boolean add(float number) {
    // adding zero doesn't modify the TextArray at all
    if (number != 0) {
        if (!Float.isNaN(lastNumber)) {
            lastNumber = number + lastNumber;
            if (lastNumber != 0) {
                set(size() - 1, new PdfNumber(lastNumber));
            } else {
                remove(size() - 1);
            }
        } else {
            lastNumber = number;
            super.add(new PdfNumber(lastNumber));
        }
        lastString = null;
        return true;
    }
    return false;
}

(PdfTextArray 方法add)

但由于取消,此代码在删除后忘记将 lastNumber 变量重置为“非数字”。因此,这个错误可以这样修复:

public boolean add(float number) {
    // adding zero doesn't modify the TextArray at all
    if (number != 0) {
        if (!Float.isNaN(lastNumber)) {
            lastNumber = number + lastNumber;
            if (lastNumber != 0) {
                set(size() - 1, new PdfNumber(lastNumber));
            } else {
                remove(size() - 1);
                lastNumber = Float.NaN;
            }
        } else {
            lastNumber = number;
            super.add(new PdfNumber(lastNumber));
        }
        lastString = null;
        return true;
    }
    return false;
}

(可以通过测试数组的最后一个位置是否有一些字符串并相应地初始化lastString来进一步改进这一点。)

这里的 iText/.Net 代码非常相似。

【讨论】:

  • 感谢您的建议。但是,它是 itext7 方面的一部分。那么,我该如何使用/更改它?
  • 好吧,iText 7 是开源的,所以你可以在代码中修复问题,编译 iText,并使用你编译的版本。或者您可以稍等片刻,直到此问题在“官方”iText 发行版中得到修复。
  • 不过,我只是看到您使用的是 7.0.10。官方发行版中的修复可能只会出现在下一个 7.1.x 中。因此,您可能需要稍微更新一下其他代码。
  • 所以,我无法解决这个问题。直到新版本到来。对吗?
  • 首先,由于您没有分享您的 pdf,我无法确定我发现的问题是否是导致您的问题的问题。堆栈跟踪只是足够相似,它可能是。但是您可以按照我的回答中的描述通过自己修复和编译 itext 来进行测试。因此,如果我发现的问题导致了您的问题,您可以快速解决问题。
猜你喜欢
  • 2019-04-25
  • 1970-01-01
  • 2021-08-31
  • 1970-01-01
  • 1970-01-01
  • 2012-05-04
  • 1970-01-01
  • 2016-09-08
  • 1970-01-01
相关资源
最近更新 更多