使用PoDoFo提取PDF文本时部分文件无输出问题咨询
PoDoFo 提取PDF文本部分文件无输出排查思路
你参考的简易文本提取实现仅覆盖了文本明文存储在内容流的场景,对普通规范PDF提取失败时,按以下优先级排查:
- 优先排查字体ToUnicode映射缺失问题:这是该类问题的最常见诱因。多数PDF不会直接存储明文文本,而是存储对应字体的字形CID编码,直接读取字符串对象拿到的是二进制索引值,没有实际字符语义,自然无有效输出。Python的PDFminer.six默认内置了CMap解析和编码映射逻辑,你参考的简易实现没有做这步处理:需要先获取当前文本操作绑定的字体对象,加载字体字典中挂载的
ToUnicodeCMap流,将读取到的字符串/十六进制串中的编码值逐位映射为Unicode字符,才能拿到正确文本。 - 排查内容流是否未解压:部分PDF的页面内容流经过FlateDecode等压缩算法处理,直接读取原始对象拿到的是压缩后的二进制数据,无法匹配到文本操作指令。需要先调用
PdfStream::GetFilteredCopy()方法获取解压后的内容流数据,再做操作符和参数解析。 - 排查文本操作符覆盖不全问题:简易实现通常只解析
Tj、TJ两个文本绘制操作符,部分PDF会使用'(换行绘制文本)、"(设置字距后换行绘制文本)两个操作符输出文本,漏解析这两个操作符会丢失全部对应内容。 - 排查输出编码不匹配问题:PoDoFo直接从
PdfString转成的std::string默认是PDFDocEncoding或UTF-16BE编码,如果直接输出到本地控制台,碰到控制台编码不兼容时也会表现为无输出。需要显式调用PdfString::GetUnicode()方法获取UTF-8编码的字符串后再做输出。
核心映射逻辑参考代码:
// 从字体对象加载ToUnicode映射 PdfObject* fontResource = page->GetFromResources(PdfName("Font"), currentFontName); if (fontResource && fontResource->IsDictionary()) { PdfObject* toUnicodeCMap = fontResource->GetDictionary().GetKey(PdfName("ToUnicode")); if (toUnicodeCMap && toUnicodeCMap->HasStream()) { char* buffer = nullptr; pdf_long bufferLen = 0; toUnicodeCMap->GetStream()->GetFilteredCopy(&buffer, &bufferLen); PdfMemoryInputStream cmapStream(buffer, bufferLen); PdfCMapEncoding unicodeCMap; unicodeCMap.AddToUnicodeMap(&cmapStream); // 后续读取到文本编码后,调用unicodeCMap.MapToUnicode()转换为实际Unicode字符 free(buffer); } }
内容的提问来源于stack exchange,提问作者Ontuvainen
相关产品推荐
相关产品推荐

