Word 与排版

Word 合并单元格为什么读出重复内容

合并单元格会在布局网格访问中重复出现,不能按文本去重。这个合成例子只构造横向合并;省略网格列需要真实合法 OOXML 样本,不能通过给行随意添加属性来模拟。

阅读文本 / Reading text
本文使用合成样本演示处理方法。代码已通过隔离环境中的示例检查;这不代表对所有真实文件或产品效果的保证。处理重要文件前,请保留原件,并按文中的边界与验收项复核。 这篇先解决哪一个问题 合并单元格会在布局网格访问中重复出现,不能按文本去重。这个合成例子只构造横向合并;省略网格列需要真实合法 OOXML 样本,不能通过给行随意添加属性来模拟。 自包含的合成示例 依赖见导入列表。代码在内存中构造输入;运行记录单独提供,不代表对所有真实文件的保证。 from docx import Document from io import BytesIO doc = Document() table = doc.add_table(rows=2, cols=3) table.cell(0, 0).merge(table.cell(0, 1)).text = "Group A" table.cell(0, 2).text = "Total" for cell, text in zip(table.rows[1].cells, ["same", "same", "20"]): cell.text = text out = BytesIO() doc.save(out) out.seek(0) restored = Document(out).tables[0] rows = [[cell.text for cell in row.cells] for row in restored.rows] assert rows[0] == ["Group A", "Group A", "Total"] assert rows[1] == ["same", "same", "20"] assert len(rows[1]) == 3 assert restored.rows[0].cells[0]._tc is restored.rows[0].cells[1]._tc assert restored.rows[1].cells[0]._tc is not restored.rows[1].cells[1]._tc 为什么读出来的表格总是“多”了数据 当你用 python-docx 遍历一个包含合并单元格的 Word 表格时,最常遇到的故障不是读不到内容,而是读到了太多内容。例如,一个视觉上占据两列的表头“项目名称”,在代码循环中会被返回两次,分别对应它覆盖的两个网格位置。如果你直接将这些文本拼接或入库,下游的数据清洗就会把同一个值误判为两条独立记录。 这并非库的 Bug,而是 Word 表格底层模型与人类视觉认知的错位。Word 表格本质上是一个不可见的“布局网格”(Layout Grid),每个单元格都必须对齐到这个网格上。合并单元格只是一个视觉对象覆盖了多个网格坐标,但在 XML 结构中,它仍然需要填满这些坐标以维持矩阵完整性。因此, row.cells 默认返回的是“网格视图”而非“视觉视图”。要正确处理表格,必须先接受这个设定:程序读取的是网格索引,而不是渲染后的方块。 错误输入与边界处理 : 若直接使用 [c.text for c in row.cells] 而不处理 grid_cols_before 和 grid_cols_after ,第一行会变成 ["标题A", "标题B"] ,导致后续所有行的列索引整体左移一位。这种错位不会报错,但会使整张表的语义彻底崩溃。对于嵌套表格(Cell 内嵌 Table),本示例仅处理顶层网格;若需递归解析,必须对每个 Cell 单独调用相同的网格对齐逻辑,不能假设外层行列数适用于内层。 基于布局网格的 Python 解析实现 这段代码的核心在于承认“重复”是合法的。在第二行中,“合并值”出现两次,是因为它在布局网格中确实占据了 (1,0) 和 (1,1) 两个位置。 关键警告 :如果你的业务逻辑需要去重,必须在解析之后根据单元格对象的内存引用(如 id(cell) )进行判断,绝不能仅凭文本值去重——因为两个独立的未合并单元格完全可能拥有相同的文本,按文本去重会导致数据丢失。 验收标准与人工审查边界 代码能解决网格对齐问题,但无法自动判定表格的语义完整性。以下表格总结了自动化解析的验收点与必须移交人工的场景。请注意,“代码演示通过”仅指网格索引对齐无误,不代表提取的内容在业务上可用。 明确不适用场景:本方法仅针对 Word 原生表格模型。对于从 PDF 转换而来、或由 HTML 粘贴生成的表格,其 XML 结构可能缺失 grid_cols_before 等关键属性,此时自动化解析结果不可信,应直接标记为待人工校对。此外,若表格使用了复杂的文字环绕或绝对定位,布局网格本身已失效,代码输出的矩阵将与视觉呈现严重不符。 参考资料与下一步 python-docx 官方文档:Working with Tables(https://python-docx.readthedocs.io/en/latest/user/tables.html) Open XML SDK 文档:Table Grid 规范(微软官方技术文档) 具体异常的处理决定 观察 应做什么 不应推断 同单元格重复 理解为网格映射 不重复翻译合并实体 两格文本相同 保留两格身份 不要按文本去重 省略网格列 另备合法 OOXML 样本 不伪造行属性测试 将这份检查清单用于文档翻译 Word 翻译容易把内容问题与格式问题混在一起。把样式、页眉和表格等检查项留到交付清单里,让审校知道该在哪里检查。 OmniDoc(产品入口) 提供多格式文档翻译入口,官网介绍了 OCR、术语表与双语对照功能。对希望直接从文件开始处理的团队,这是一条值得用实际样本评估的路径。请使用有权上传的脱敏文件,并用本篇的检查项复核结果;这里不声称 OmniDoc 使用了本文的开源库或内部算法,也不以示例代替产品性能测试。 - 1 -
更新于 2026-10-09