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

使用python-docx读取Word表格时表头边框对齐异常致数据重复

解决方案:处理Word表格读取列数异常问题

方案一:修复Word表格结构(从根源解决)

你的问题核心是表格行的单元格数量不一致(表头行和内容行的拆分/合并单元格导致列数混乱),仅设置单元格宽度无法解决结构问题。可以先统一所有行的单元格数量为6,再调整列宽度:

from docx import Document
from docx.shared import Inches

doc = Document("original.docx")
table = doc.tables[6]
target_cols = 6  # 目标列数

# 统一每行的单元格数量
for row in table.rows:
    current_cell_count = len(row.cells)
    if current_cell_count > target_cols:
        # 合并多余的单元格,保留前target_cols个
        merge_start_idx = target_cols - 1
        for idx in range(merge_start_idx + 1, current_cell_count):
            row.cells[merge_start_idx].merge(row.cells[idx])
    elif current_cell_count < target_cols:
        # 拆分单元格补充列数
        while len(row.cells) < target_cols:
            row.cells[-1].split(2)

# 关闭自动调整,设置统一列宽
table.autofit = False
table.allow_autofit = False
col_width = Inches(2)
for col in table.columns:
    for cell in col.cells:
        cell.width = col_width

doc.save("fixed_document.docx")

说明

  • 先将所有行的单元格数量强制统一为6,处理多列合并、少列拆分的情况
  • 再设置每列的固定宽度,确保表格结构一致,重新读取即可得到正确的6列数据

方案二:清理读取数据,重建正确DataFrame(你倾向的方案)

如果不想修改原Word文件,可以直接处理读取后的11列数据,通过识别合并单元格的规律,将拆分的列合并为6列:

步骤1:读取原始表格数据

from docx import Document
import pandas as pd

doc = Document("original.docx")
table = doc.tables[6]

# 读取所有行的单元格文本
raw_data = []
for row in table.rows:
    raw_data.append([cell.text.strip() for cell in row.cells])

步骤2:自定义合并规则(关键)

需要先分析raw_data中11列对应实际6列的分组规律(比如哪些列是同一单元格拆分出来的),示例如下:

# 假设实际6列对应的11列分组(根据你的表格实际情况调整)
merge_groups = [(0, 1), (2, 3), (4, 5), (6, 7), (8, 9), (10)]

# 合并每组列的文本,去空去重
cleaned_data = []
for row in raw_data:
    cleaned_row = []
    for group in merge_groups:
        combined_text = " ".join([row[i] for i in group if row[i]]).strip()
        cleaned_row.append(combined_text)
    cleaned_data.append(cleaned_row)

步骤3:生成正确的DataFrame

# 假设前两行是表头,可合并表头或选取其中一行作为列名
# 示例:用第二行作为列名,从第三行开始作为数据
df = pd.DataFrame(cleaned_data[2:], columns=cleaned_data[1])
print(df)

进阶:自动识别合并单元格

如果表格合并规则复杂,可以通过判断单元格的合并属性自动生成分组:

def is_merged_cell(cell):
    # 判断单元格是否为纵向合并的后续单元格(非起始单元格)
    tc = cell._tc
    v_merge = tc.xpath("./w:tcPr/w:vMerge")
    if v_merge:
        return v_merge[0].get("w:val") != "restart"
    return False

# 遍历表头行,识别合并的单元格位置,生成合并规则
header_row = table.rows[0]
merge_groups = []
current_group = []
for idx, cell in enumerate(header_row.cells):
    current_group.append(idx)
    # 如果下一个单元格是合并的,继续加入当前组
    if idx + 1 >= len(header_row.cells) or not is_merged_cell(header_row.cells[idx+1]):
        merge_groups.append(tuple(current_group))
        current_group = []

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.08 17:07:41