Java iText";坐标超出允许范围”;使用LocationTextLocationStrategy的异常
尝试使用Java iText";坐标超出允许范围”;使用LocationTextLocationStrategy的异常,java,exception,itext,itext7,Java,Exception,Itext,Itext7,尝试使用LocationTextExtractionsStrategy时引发异常“坐标超出允许范围” for (int pageNum = 1; pageNum <= document.getNumberOfPages(); pageNum++) { PdfPage page = document.getPage(pageNum); sb.append(PdfTextExtractor.getTextFromPage(page, new LocationTextExtrac
LocationTextExtractionsStrategy
时引发异常“坐标超出允许范围”
for (int pageNum = 1; pageNum <= document.getNumberOfPages(); pageNum++)
{
PdfPage page = document.getPage(pageNum);
sb.append(PdfTextExtractor.getTextFromPage(page, new LocationTextExtractionStrategy()));
}
我有两个类似的PDF由同一个软件生成,第一个是抛出异常,第二个不是
在第一个PDF中引发此异常的是什么?如何在不使用SimpleText策略的情况下解决此问题?(根据堆栈跟踪,您使用的是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乘3个单位;最大值应为14400乘以14400个单位
41879*0.802969
单位高,即约为33628
单位,仅为需要支持的两倍多。出于某些原因,iText似乎仍然支持这一点
如何在不使用SimpleText策略的情况下解决此问题?
通过更改常量com.itextpdf.kernel.pdf.canvas.parser.clipper.ClipperBridge.floatMultiplier
/**
* 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应该考虑当前极限是否是这样的实际极限或应该放宽。
/**
* 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);