Files
hermes-skills/skills/legal/contract-editor/references/table-cell-format-preservation.md
T

2.3 KiB

表格单元格编辑:保持格式不被破坏

问题

编辑 docx 表格单元格中的文字时,两种常见错误做法都会破坏格式:

  1. cell.paragraphs[0].clear() + add_run():把多段结构压成一段,丢失加粗、字号、字体
  2. XML 层全 cell 文字重分片:把修改后的文字均匀分配到所有 w:t 元素,破坏段落边界和编号

正确做法:段落级精确定位 + 只改目标段

from docx import Document
from docx.shared import Pt

doc = Document('file.docx')
table = doc.tables[0]
cell = table.rows[7].cells[1]

# 1. 定位目标段落(按索引)
paras = cell.paragraphs
target_p = paras[4]  # 例如 P4 是你要改的段落

# 2. 保存首 run 格式
first_run = target_p.runs[0]
saved = {
    'name': first_run.font.name,
    'size': first_run.font.size,
    'bold': first_run.font.bold,
    'italic': first_run.font.italic,
}

# 3. 文字替换
old_text = target_p.text
new_text = old_text.replace('要被替换的文字', '新文字')

# 4. 清空该段 → 重写(保留格式)
target_p.clear()
run = target_p.add_run(new_text)
run.font.name = saved['name']
run.font.size = saved['size']
run.font.bold = saved['bold']
run.font.italic = saved['italic']

# 5. 合并单元格:同步更新同行其他 cell
for col_idx in [2, 3]:
    cell2 = table.rows[7].cells[col_idx]
    p = cell2.paragraphs[4]
    p.clear()
    run = p.add_run(new_text)
    run.font.name = saved['name']
    run.font.size = saved['size']

doc.save('output.docx')

关键原则

  • 不碰其他段落:只改目标索引的段落,其余段落原封不动
  • 不压多段为一段:每个段落独立处理,保持 P0/P1/P2/P3/P4 结构不变
  • 合并单元格全同步row[7].cells[1] 改了什么,cells[2]cells[3] 也要同步
  • 先读后改:改前用 cell.paragraphs[i].text 确认内容,用 cell.paragraphs[i].runs[0].font 确认格式

本次教训

2026-06-26 预算绩效分析表:两轮都搞坏格式。

  • 第一轮:clear() + add_run() 把 Row 7 的 P0-P10 多段结构压成一段
  • 第二轮:XML 全 cell 文字重分片把 "2.成本核算分析" 变成 ".成本核算分析"(编号丢失)
  • 第三轮(正确):定位到 P4(成本优化段),只改它,保留 P0-P3 不动