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

如何用pdfplumber合并跨页拆分表格行?能否识别行水平边框?

利用pdfplumber识别水平边框合并跨页拆分的表格行

完全可以通过识别单元格的水平边框来辅助合并跨页拆分的表格行——这类拆分的行通常有明显的边框特征:上一页的拆分行底部没有完整的水平边框,下一页对应的延续行顶部没有水平边框,我们可以基于这个规则实现合并逻辑。

实现思路

  1. 提取带边框信息的单元格:使用pdfplumber的extract_cells方法(而非直接提取文本行),获取每个单元格的边框属性(edges字段,包含top/bottom/left/right四个方向的边框存在状态)。
  2. 标记不完整行:遍历每页的表格单元格,标记出底部无水平边框的行(可能是跨页拆分的上半部分),以及顶部无水平边框的行(可能是拆分的下半部分)。
  3. 合并延续行:将上一页留存的无底部边框行,与当前页开头无顶部边框的行进行内容合并,形成完整的单行。

代码示例

import pdfplumber
import csv

def merge_cross_page_rows(input_pdf, output_csv):
    incomplete_row = None
    with open(output_csv, 'w', newline='', encoding='utf-8') as csv_out:
        writer = csv.writer(csv_out)
        with pdfplumber.open(input_pdf) as pdf:
            for page in pdf.pages:
                # 基于线条识别表格,提取带边框信息的单元格
                cells = page.extract_cells(table_settings={
                    "vertical_strategy": "lines",
                    "horizontal_strategy": "lines"
                })
                if not cells:
                    continue
                # 计算每行的单元格数量(假设表格结构规整)
                row_cell_count = len(page.extract_table()[0])
                # 按行分组单元格
                rows_cells = [cells[i:i+row_cell_count] for i in range(0, len(cells), row_cell_count)]
                # 提取每行的文本内容
                rows_text = []
                for row_cells in rows_cells:
                    row_text = [cell.get('text', '').strip() for cell in row_cells]
                    rows_text.append(row_text)
                
                # 处理当前页的行,结合上一页的不完整行
                processed_rows = []
                for idx, row in enumerate(rows_text):
                    current_row_cells = rows_cells[idx]
                    # 检查当前行是否有顶部边框
                    has_top_border = any(cell['edges']['top'] for cell in current_row_cells)
                    # 若存在未完成的行,且当前行无顶部边框,判定为延续行并合并
                    if incomplete_row is not None and not has_top_border:
                        merged_row = [f"{incomplete_row[i]}{row[i]}" if row[i] else incomplete_row[i] for i in range(len(row))]
                        processed_rows.append(merged_row)
                        incomplete_row = None
                    else:
                        # 检查当前行是否有底部边框,无则标记为不完整行
                        has_bottom_border = any(cell['edges']['bottom'] for cell in current_row_cells)
                        if not has_bottom_border:
                            incomplete_row = row.copy()
                        else:
                            processed_rows.append(row)
                # 写入当前页处理后的行
                writer.writerows(processed_rows)
            # 处理最后一页剩余的不完整行
            if incomplete_row is not None:
                writer.writerow(incomplete_row)

# 调用示例
merge_cross_page_rows("cross_page_table.pdf", "merged_result.csv")

注意事项

  • 该方法仅适用于基于线条绘制的表格,纯靠文本对齐的无框表格无法使用此逻辑。
  • 若表格存在跨行合并的单元格,需额外调整行分组逻辑,避免单元格数量不一致导致的分组错误。
  • 部分PDF的边框线条较细或偏移,可调整table_settings中的edge_min_length参数优化边框识别精度。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 22:15:29