属性错误 - 使用Borb检测PDF中的表格
我需要在PDF文件中检测表格,这样我才能在空白单元格中创建字段表单。
为了测试borb这个工具是否能实现这个目标,我尝试使用作者的示例作为参考。
我的代码是:
from decimal import Decimal
from borb.pdf import Document
from borb.pdf.page.page import Page
from borb.pdf.pdf import PDF
from borb.toolkit.table.table_detection_by_lines import TableDetectionByLines as TDBL
from borb.pdf.canvas.layout.annotation.square_annotation import SquareAnnotation
from borb.pdf.canvas.color.color import HexColor, X11Color
def main(infile, outfile):
# get doc
t = TDBL()
doc = None
with open(infile, "rb") as pdf_file_handle:
doc = PDF.loads(pdf_file_handle, [t])
assert doc is not None
# get page
p = doc.get_page(0)
# get Tables
for r in t.get_table_bounding_boxes():
r = r.grow(Decimal(5))
p.add_annotation(SquareAnnotation(r, stroke_color=X11Color("Green")))
with open(outfile, "wb") as pdf_file_handle:
PDF.dumps(pdf_file_handle, doc)
return
if __name__ == "__main__":
infile = "Parameter.pdf"
outfile = "ParameterOut.pdf"
main(infile, outfile)
我在这里使用了自己的PDF文件:"Parameter.pdf"。
当我运行程序时,出现了这个错误:
# etc..
r = r.grow(Decimal(5))
AttributeError: 'int' object has no attribute 'grow'
我哪里出错了?
1 个回答
免责声明:我是 borb
的作者
0. 关于 borb
请查看 get_table_bounding_boxes
的签名:
def get_table_bounding_boxes(self) -> typing.Dict[int, typing.List[Rectangle]]:
"""
This function returns the bounding boxes (as Rectangle objects) of each Table
that was recognized on the given page.
"""
简单来说,这个方法返回的是一个 dict
,而不是一个 list[Rectangle]
。
这就是你代码出错的地方。你试图在一个不是 Rectangle
的东西上调用 grow
。
1. 关于你的PDF
免责声明2:我检查了你的文档。我可能错了。但这是我对发生情况的理解。
你的PDF有些奇怪。在最基本的层面上,PDF文档使用后处理指令在页面上绘制东西(线条、曲线、图像、文本)。这些后处理指令通常以压缩的形式存储在PDF中。
我解压了你的PDF。它包含以下指令:
q
72.504 706.06 77.4 13.464 re
W* n
/Span <</MCID 0/Lang (en-US)>> BDC q
72.504 706.06 77.4 13.464 re
W* n
BT
/F1 11.04 Tf
1 0 0 1 77.664 709.06 Tm
/GS10 gs
0 g
/GS11 gs
0 G
[<0057>17<0102018C>24<01020175>6<011E>9<019A>9<011E018C>] TJ
ET
Q
现在来解释一下(你可以在PDF规范中查看,附录A - 操作符摘要。规范的副本可以在borb库中找到):
q
: 保存图形状态
re
: 将矩形添加到路径中
W*
: 使用奇偶规则设置剪切路径
n
: 结束路径,不填充或描边
所以,你的文档是在指示PDF查看器将一个矩形添加到路径中,但之后却没有发出实际填充或描边该路径的指令。
为了强调这一点,规范对 re
操作符的解释是:
将一个矩形作为完整的子路径添加到当前路径中,左下角坐标为 (x, y),宽度和高度在用户空间中。操作
x y width height re
等同于
x y m
( x + width ) y l
( x + width ) ( y + height ) l
x ( y + height ) l
h
l
: 从当前点到 (x, y) 的直线段。新的当前点将是 (x, y)。
h
: 通过从当前点到子路径起始点添加一条直线段来关闭当前子路径。如果当前子路径已经关闭,h 将不执行任何操作。这个操作结束当前子路径。向当前路径添加另一个段将开始一个新的子路径,即使新段的起点是通过 h 操作到达的端点。
而且PDF规范明确区分了构建路径(并关闭它)和实际描边或填充它。
在表60 - 路径绘制操作符中,你可以找到证据:
S
: 描边路径。
s
: 关闭并描边路径。这个操作符的效果与序列 h S 相同。