PDF表格数据

时间:2012-12-22 10:19:36

标签: parsing pdf text-extraction

我有一个关于从pdf文件中提取文本,精确表格数据的一般性问题。

pdf查看器如何读取和显示表格?为什么我们不能以同样的方式获得必要的列信息呢?

我现在正在搜索这个问题一周,主要是使用pdftoxml来处理令牌坐标和太宽的表格单元格(这样就无法准确地进行中间空表格单元识别)。

我通过对文本进行重新定位来解决这一问题(如果某些行间距离被忽略并“粘贴在一起”,那么顺便说一句,这是非常成功的),但这当然只是一个实例解决方案

这给了我一个根据。 pdf查看器为单元格绘制线条并知道单元格的开始和结束位置,但我们无法从pdf源中读取这些内容。这怎么可能呢?他们知道我们无法推断出什么?

2 个答案:

答案 0 :(得分:5)

您的错误观念是列作为列存储在PDF文件中。事实并非如此。 PDF查看器无法理解表格,列,段落,文本行或单词。

PDF是作为页面描述语言创建的,它非常适合在许多不同设备上再现完全相同的页面。因为这是它的目标,它不关心结构,你所指的是所有结构。

PDF绘制文本的方式非常非常简单。页面上的说明将是这样的:

  • 设置此字体
  • 转到页面上的这一点
  • 渲染这些字符。
  • 转到页面上的另一个点
  • 渲染更多角色。

虽然也可以将这些结构信息与这些说明一起存储在PDF中,但通常不会这样做,而且无论如何都是以PDF格式实现的。

当您查看上面的(伪)指令时,很容易理解如何绘制表格。文件中只会有指令移动到一个单元格的某个位置并绘制文本。然后有更多指令移动到另一个单元格并绘制该文本。

如果要反转操作并从PDF页面中提取结构化信息,则必须“重新发明”结构信息。这意味着要确定哪些文本位于同一基线上,因此可能属于同一条线。哪个文本在该基线上足够接近,以便它可能是单词或列......等等......

你已经想通了,这根本不是一件容易的事!

答案 1 :(得分:-2)

在未压缩的pdf文档中,以伪正则表达式形式存在以下不确定格式((0,0)左下角)的“流对象”:

(x1 y1 m x2 y2 l [whitespace or blank or newline seperator symbol])* S (BT .* ET)*

,其中

x1, y1, x2, y2 are coordinates
l probably for "draw line"
m move to, "from to" or "merge"
S is the command for "draw" or the like
BT Begin Text
ET End Text

所有命令后缀。

编辑:

一个可能的Java regexp是(ref PDF32000_2008.pdf),在未压缩的pdf源中用空格替换换行符之后:

((\s+\d+(\.\d+)?){2}(\s+m|\s+l|(\s+\d+(\.\d+)?){2}(\s+re|\s+y|\s+v|(\s+\d+(\.\d+)?){2}\s+c))\s+)+([SsFn]|[fBb](\*)?) 

流中还有其他元素,如“W *”或“Q q”,它们似乎通常会调整线条粗细或字体属性。由于我无法找到特定的语言规范,这是我从实验中推断的。

使用此信息和文本标记的坐标(在ET和BT之间),可以推断表格单元格宽度,表格起始结束位置(用于标识不同的表格)。

问题仍然是解压缩任何类型的流。使用pdftk,我能够解压缩从openoffice writer创建的pdf文件,但任意pdf文件中仍然有神秘的符号。

更多信息:

http://www.gnupdf.org/Introduction_to_PDF

http://blog.idrsolutions.com/2011/05/understanding-the-pdf-file-format-%E2%80%93-carriage-returns-spaces-and-other-gaps/

http://blog.idrsolutions.com/2012/03/understanding-the-pdf-file-format-names-locations/

http://blog.idrsolutions.com/2011/05/understanding-the-pdf-file-format-%E2%80%93-pdf-xref-tables-explained/

PDF page-stream optimizer library?

http://www.gnupdf.org/Stream