如何使用iText解析未标记的pdf文件

Hun*_*nsu 2 java pdf itext pdf-parsing

我想用iText 解析这个文件(http://www.bbm.ca/_documents/top_30_tv_programs_english/2011/nat01032011.pdf).问题是它没有被标记,所以我无法获取XML文件.我决定从中提取文本,我认为例如第一行将是:

1\specialCharWJC:PLAYOFFS CANADA\specialCharTSN+\specialCharM.W....\specialChar19:30\specialChar21:57\specialChar5133
Run Code Online (Sandbox Code Playgroud)

我为第一行提取的文字是

1 WJC:PLAYOFFS CANADA TSN+ M.W.... 19:30 21:57 5133
Run Code Online (Sandbox Code Playgroud)

我使用以下方法提取文本:

PdfReader reader = new PdfReader(filename);
String str = PdfTextExtractor.getTextFromPage(reader, 1);
Run Code Online (Sandbox Code Playgroud)

PDf观众如何知道加拿大在第二列不在第三列.

我目前的解决方案是使用http://www.idrsolutions.com/online-pdf-to-html5-converter/将pdf文件转换为html5 ,后者可以确定每列的文本.

感谢您的答复

Kev*_*Day 5

我写了iText文本提取器.在iText中有两种提取策略 - 一种是天真的(更多的概念证明),它只是在文本命中时转储.另一个(LocationTextExtractionStrategy)更精确,它使用@Jongware建议的位置和字体信息来构建字符串(它还考虑了所有坐标转换).如果你像你一样调用getTextFromPage(),后者是默认策略.

行20文本显示两次的原因是b/c一些PDF生成者这样做来模拟一个粗体字形(它们将字符移动一点并重新渲染).所以这不是一个错误,真的 - 但肯定可能是一个改进的机会.如果我们发现相同内容的块落在彼此的某个缇区域内,我们可能会做一些事情.我们之所以没有这样做的原因是,这可能真的很棘手,b/c你可能有一个块是整个单词,另一组块 - 每个字母一个.我们有能力进行子块分析(事实上,这是在某个地方的解析器界面中暴露出来的 - 无法回想起 - 让我知道你是否需要它,我会追踪它) - 但那会是由于性能损失很大,所以我不愿意这样做.

无论如何,我解决这个特定挑战的方式是设置物理区域并将区域过滤器传递给LocationTextExtractionStrategy#getResultantText()调用.

如果你真的需要根据文本的水平位置插入制表符(或一些列标记),这是非常可行的 - 看一下在LocationTextExtractionStrategy源代码中调用isChunkAtWordBoundary()方法的位置并添加自己的处理程序用于在空格之外插入特殊字符.也可以进行某种上下文分析(即注意到有一堆块碰巧共享相同的X位置和方向,并将X位置指定为制表位).

如果你想出一个很好且通用的想法(即不是特定于这个解析任务),请告诉我,我会看到我可以做些什么来将它合并到iText中.

  • @Jongware如果你在内容流中看它,它会变得更有趣.第一次出现的文本是用一个太小的剪切矩形绘制的,主动切掉文本的下半部分.然后在该区域填充一个矩形.然后再次出现文本,这次是它适合的剪辑路径,并且字符和字间距设置略有不同.好像某些自动输出不满足,然后手动修正,用于修正的程序引入了一些自己的角色定位思路. (2认同)