You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用Python提取PDF表格内无文本的阴影单元格

解决方案

问题本质

基于文本流、表格线条识别的PDF提取工具(包括tabula-py、PyPDF2、pdfminer),仅会提取单元格内的可编码文本内容。阴影单元格属于PDF的图形填充元素,不属于文本或表格边框范畴,这类工具默认不解析填充属性,无法识别对应标记。


优先方案:用camelot-py直接读取单元格填充属性

camelot的lattice解析模式会直接读取PDF页面的绘图指令流,不需要转图像就能识别单元格的填充色,是成本最低的实现方式:

  1. 安装依赖
    • 先装系统依赖ghostscript:Windows下载安装包配置环境变量即可,Mac执行brew install ghostscript,Ubuntu执行apt install ghostscript python3-tk
    • 安装Python库:pip install camelot-py[cv] pandas
  2. 核心实现代码
import camelot
import pandas as pd

# 读取PDF第32页表格,lattice模式适配带明确边框线的表格
tables = camelot.read_pdf(
    "target_file.pdf",
    pages="32",
    flavor="lattice",
    line_scale=40 # 调大该值可提升细表格线的识别率
)

# 遍历单元格,通过填充色标记阴影单元格
table = tables[0]
shadow_cells = []
for row_idx, row in enumerate(table.cells):
    for col_idx, cell in enumerate(row):
        # 非白色填充判定为阴影单元格,可根据实际阴影灰度调整判定规则
        if cell.fill and cell.fill != (255, 255, 255):
            shadow_cells.append((row_idx, col_idx))

# 输出补全后的完整表格
df = table.df
for r, c in shadow_cells:
    df.iloc[r, c] = "[阴影标记]" # 替换为阴影单元格对应的实际业务值
print(df)
  • 如果camelot识别表格行列错位,可微调line_scale、copy_text参数,或手动传入table_area参数指定表格精确坐标,提升识别率。

备选方案:渲染图像+灰度检测

如果camelot无法正确识别填充属性(比如部分PDF的阴影是独立叠层矩形,未绑定到单元格属性上),可使用渲染后图像检测的方案:

  1. 安装依赖:pip install pdf2image opencv-python numpy tabula-py,同时安装poppler工具供pdf2image调用。
  2. 实现逻辑
    • 将目标PDF页渲染为300DPI的高清图像
    • 用tabula输出json格式结果,拿到所有单元格的边界坐标,按DPI缩放系数换算为图像像素坐标
    • 遍历每个单元格对应的图像区域,计算区域平均灰度值,低于白色阈值的判定为阴影单元格
    • 合并文本提取结果和阴影检测结果,补全全量表格内容
  • 注意:PDF原生坐标系原点在左下角,渲染后图像原点在左上角,Y轴坐标需要做翻转换算,避免区域匹配错位。

高自由度方案:用PyMuPDF自解析

如果上述两个方案识别效果达不到要求,可直接用PyMuPDF(fitz)库解析页面元素:

  • 直接读取页面所有绘图指令,提取所有带灰度填充的矩形块坐标
  • 读取页面所有文本块的坐标
  • 自行按坐标做行列对齐,划分表格网格,匹配文本和阴影块到对应单元格
    这个方案灵活度最高,不受第三方表格识别库的规则限制,但需要自行处理行列对齐逻辑,适合结构特殊的表格。

  • 调参提示:阴影的灰度阈值不要硬编码,先取一个已知阴影单元格的颜色值做校准,避免把表格线、文字像素误判为阴影填充。

内容的提问来源于stack exchange,提问作者Max Bromet

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.09.03 06:33:29