使用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
相关产品推荐
相关产品推荐

