iText 7.x读取PDF时部分关键文本缺失的问题求助
检查区域过滤的有效性
PDF的坐标系以页面左下角为原点,你设置的Rectangle(0, 0, 1100, 1100)可能和目标页面实际尺寸不匹配,导致缺失文本不在过滤区域内。可以先获取页面实际尺寸:PdfPage page = pdfDocument.GetPage(i); Rectangle pageSize = page.GetPageSizeWithRotation();用实际页面尺寸调整过滤区域,或者暂时去掉
FilteredTextEventListener,直接提取整页文本,看缺失内容是否能被提取,以此排除区域过滤的问题。更换文本提取策略
LocationTextExtractionStrategy是按文本位置排序提取,但某些PDF的文本布局特殊(比如文本块顺序混乱、存在重叠文本),可以尝试用SimpleTextExtractionStrategy,它按PDF内容流的顺序提取文本:inputStr = PdfTextExtractor.GetTextFromPage(pdfDocument.GetPage(i), new SimpleTextExtractionStrategy());也可以自定义提取策略,继承
LocationTextExtractionStrategy并重写相关方法,或者使用FontTextExtractionStrategy针对字体相关问题排查。排查PDF文本的存储形式
- 如果缺失文本是图片格式(比如扫描件、嵌入的图片文本),iText的文本提取功能无法直接识别,需要结合OCR工具处理。
- 检查PDF是否将文本以矢量图形路径绘制而非文本对象存储,这种情况也无法直接提取文本,同样需要OCR辅助。
处理字体与编码问题
部分PDF使用未嵌入的字体或自定义编码,iText可能无法正确解析字符。可以检查PDF的字体属性:PdfDictionary resources = page.GetResources(); PdfDictionary fontDict = resources.GetAsDictionary(PdfName.Font); // 遍历字体字典,检查是否嵌入、编码方式 foreach (PdfName fontName in fontDict.KeySet()) { PdfDictionary font = fontDict.GetAsDictionary(fontName); bool isEmbedded = font.GetAsStream(PdfName.FontFile2) != null; // 输出字体信息排查 }对于编码异常的情况,可以尝试设置提取策略的编码映射,或者使用iText的
PdfFontFactory重新加载字体。检查页面旋转与表单/注释文本
- 如果页面存在旋转,会导致坐标偏移,需先获取页面旋转角度并调整过滤区域:
int rotation = page.GetRotation(); // 根据旋转角度调整Rectangle的坐标 - 若缺失文本在表单域或注释中,
LocationTextExtractionStrategy不会提取这类内容,需要单独处理:- 提取表单域文本:遍历
pdfDocument.GetAcroForm().GetFields()获取字段值。 - 提取注释文本:遍历
page.GetAnnotations(),从PdfAnnotation中获取文本内容。
- 提取表单域文本:遍历
- 如果页面存在旋转,会导致坐标偏移,需先获取页面旋转角度并调整过滤区域:
排查隐藏文本或特殊渲染模式
某些PDF会设置文本的渲染模式为不可见(但视觉上通过其他方式显示),可以在自定义提取策略中重写RenderText方法,查看TextRenderInfo的GetRenderMode(),若返回PdfCanvasConstants.TextRenderMode.INVISIBLE,则需要特殊处理这类文本。
内容的提问来源于stack exchange,提问作者Yaniv Amrami

