当我尝试使用LocationTextExtractionStrategy
时,会抛出异常"坐标超出允许的范围"。
for (int pageNum = 1; pageNum <= document.getNumberOfPages(); pageNum++)
{
PdfPage page = document.getPage(pageNum);
sb.append(PdfTextExtractor.getTextFromPage(page, new LocationTextExtractionStrategy()));
}
有关异常的详细信息:
java.lang.IllegalStateException: Coordinate outside allowed range
at com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBase.rangeTest(ClipperBase.java:76)
我有 2 个由同一软件生成的类似 PDF,第一个是抛出异常,第二个不是。
PDF 1(例外)
PDF 2 (好的)
在第一个 PDF 中引发此异常的原因是什么?如何在不使用 SimpleTextExtractionStrategy 的情况下解决此问题?
(根据您的堆栈跟踪,您使用的是iText 7.*版本。我相应地更新了您的问题标签,并使用当前的iText 7.1.2-SNAPSHOT重现了该问题。
在第一个 PDF 中引发此异常的原因是什么?
总之
您的两个 PDF 都包含用于定义剪辑路径的极端y坐标(超出 ISO 32000-1 实施限制),您的 PDF 1 仅是 PDF 2 的两倍极端,iText 剪辑路径例程开始在两者之间打嗝。
详细地
PDF 1 第 1 页的页面内容流基本上如下所示:
q
[...]
% modifyCTM
0.802969 0 0 -0.802969 0 842 cm
[...]
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
q
0 0 741 98417 re W n
[...]
Q
Q
因此,即使考虑到CTM的初始修改,您也会六次定义剪辑路径矩形,其高度为98417 * 0.802969
默认用户单位,大约等于79026
默认用户单位。
另一方面,ISO 32000-1附录C.2架构限制表明
符合要求的读者应容纳遵守约束的 PDF 文件。
[...]
- 默认用户空间中的最小页面大小应为 3 x 3 个单位;最大页面大小应为 14,400 x 14,400 个单位。
因此,剪辑路径矩形的高度是符合要求的读者应支持的页面的五倍以上。因此,符合标准的阅读器不需要支持您的极端剪辑路径。
PDF 2 的构建方式类似,所讨论的剪辑路径仅高41879 * 0.802969
个单位,即大约33628
个单位,仅是需要支持的两倍多。出于某些原因,iText似乎仍然支持这一点。
如何在不使用 SimpleTextExtractionStrategy 的情况下解决此问题?
您可以通过更改常量com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBridge.floatMultiplier
来调整iText 7
/**
* Since the clipper library uses integer coordinates, we should convert
* our floating point numbers into fixed point numbers by multiplying by
* this coefficient. Vary it to adjust the preciseness of the calculations.
*/
public static double floatMultiplier = Math.pow(10, 14);
您可以尝试例如Math.pow(10, 10)
这对我的两个文件都有效。
话虽如此,ISO 32000-2似乎已经放弃了这个特定的页面大小限制,只是有更通用的限制加上语句,例如在特定设备上运行的特定PDF处理器和在特定操作环境中总是有实际限制。
因此,@iText应考虑目前的限制是这样的实际限制还是应该放宽。