2011-01-11 119 views
2

我正在使用PDFBox从PDF中提取文本。 PDF有一个表格结构,它非常简单,列间距也非常宽。保留PDFBox文本提取中的“long”空格

这个工作非常好,除了所有类型的水平空间都被转换为单个空格字符,所以我不能再分开各列(一列中的空格看起来就像列之间的空格)。

我明白,一个通用的解决方案是很辛苦,但在这种情况下,列是真的相距甚远,使得具有“长间隔”和“字与字之间的空间”之间的简单区别就足够了。

有没有办法告诉PDFBox将多于x英寸的水平空白转换为单个空间以外的东西?比例方法(x英寸变成y空格)也可以工作。

pdftotext C library/tool有一个'-layout'开关,试图保留布局。基本上,如果我可以用PDFBox来模拟,那将是完美的。

+0

你可能想看看[这个答案](https://stackoverflow.com/a/45842515/1729265)。 – mkl 2017-10-16 04:18:41

回答

2

似乎没有为此设置,但我可以修改PDFTextStripper工具的源以在遇到“长”空间时输出列分隔符(|)。在构建输出行的代码中,可以查看当前字母和前一个字母的x位置,并且如果足够大,请执行特殊操作。 PDFTextStripper拥有许多受保护的方法,但事实证明它们并非全部可扩展。我最终不得不复制整个班级来改变私人方法。

看看那里的代码,我称自己很幸运,使用特定的PDF,这种简单的方法是成功的。更普遍的解决方案似乎非常棘手。

+1

你必须改变哪种私人方法,你是如何改变它的? – 2015-12-18 15:16:17

1

PDF文本提取很困难。

如果文本是输出作为一个大的字符串由空格等隔开: -

PDFTextOut("  Column 1     Column 2   Column 3"); 

并且正在使用固定宽度的字体,例如信使则理论上可以计算出的空间的项之间的数因为每个字符都是相同的宽度。如果字体与Arial成比例,则计算更困难。

在现实中大多数的PDF文件的每个文本块逐个放到直接到其位置上产生。因此,技术上没有空格字符或列之间的任何其他字符。文本只是放置在页面上的绝对位置。

PDFMoveTo(100,100); 
PDFTextOut("Column 1"); 
PDFMoveTo(250,100); 
PDFTextOut("Column 2"); 

为了对PDF文档进行数据抽取你必须做一点点工作,通过匹配列数据使用像素位置,你所提到的和做一些假设,并有一点点的发现和运气。

+1

好,PDF文本提取是困难的,但xpdf中的pdftotext的布局保存选项工作得很好。将是不错的有类似的东西PDFBox的(已经成功地保存阅读顺序,在将文本在同一行到相同的输出线,并在分组字成词)。这个明文输出是否足够清晰以满足以下解析逻辑(即必须重构表格),这是另一个问题。幸运的是,在我的情况下,它的工作。 – Thilo 2011-01-12 07:13:52