4.4 KiB
4.4 KiB
审查意见文档字体强制设置
背景(2026-07-02 肃言+恭兴合同返工)
review-rules.md 规定审查意见文档:中文统一仿宋体,英文Times New Roman。
问题:模板文件(朱家角 审查意见【模板】.docx)的表头行有显式eastAsia=仿宋,但新建的数据行字体设置不一致:
- 恭兴审查意见:editor给数据行设了 ascii=仿宋 hAnsi=仿宋(错:英文也变仿宋了)
- 肃言审查意见:editor压根没给数据行设ascii/hAnsi(只有eastAsia=仿宋)
根因:LLM每次独立session生成代码,字体设置逻辑不稳定。
强制修复代码(生成审查意见后必跑)
from docx import Document
from docx.oxml.ns import qn
from docx.oxml import OxmlElement
def enforce_review_opinion_fonts(doc_path, save=True):
"""审查意见文档生成后强制设置所有run的字体。
中文=仿宋, 英文=Times New Roman
"""
doc = Document(doc_path)
fixed = 0
# Fix all table cells
for table in doc.tables:
for row in table.rows:
for cell in row.cells:
for p in cell.paragraphs:
for run in p.runs:
fixed += _fix_run_font(run._element)
# Fix all paragraphs outside tables
for p in doc.paragraphs:
for run in p.runs:
fixed += _fix_run_font(run._element)
if save:
doc.save(doc_path)
return fixed
def _fix_run_font(run_element):
"""Ensure run has eastAsia=仿宋, ascii/hAnsi=Times New Roman"""
rPr = run_element.find(qn('w:rPr'))
if rPr is None:
rPr = OxmlElement('w:rPr')
run_element.insert(0, rPr)
rFonts = rPr.find(qn('w:rFonts'))
if rFonts is None:
rFonts = OxmlElement('w:rFonts')
rPr.insert(0, rFonts)
changed = False
# eastAsia must be 仿宋
if rFonts.get(qn('w:eastAsia')) != '仿宋':
rFonts.set(qn('w:eastAsia'), '仿宋')
changed = True
# ascii must be Times New Roman (NOT 仿宋)
if rFonts.get(qn('w:ascii')) != 'Times New Roman':
rFonts.set(qn('w:ascii'), 'Times New Roman')
changed = True
# hAnsi must be Times New Roman (NOT 仿宋)
if rFonts.get(qn('w:hAnsi')) != 'Times New Roman':
rFonts.set(qn('w:hAnsi'), 'Times New Roman')
changed = True
return 1 if changed else 0
验证方法
def verify_review_opinion_fonts(doc_path):
"""验证审查意见文档字体全部正确"""
from docx import Document
from docx.oxml.ns import qn
doc = Document(doc_path)
errors = []
for table in doc.tables:
for i, row in enumerate(table.rows):
for j, cell in enumerate(row.cells):
for p in cell.paragraphs:
for run in p.runs:
rpr = run._element.find(qn('w:rPr'))
if rpr is None:
errors.append(f'Row{i}Col{j}: no rPr')
continue
rf = rpr.find(qn('w:rFonts'))
if rf is None:
errors.append(f'Row{i}Col{j}: no rFonts')
continue
ea = rf.get(qn('w:eastAsia'))
ascii_f = rf.get(qn('w:ascii'))
hAnsi = rf.get(qn('w:hAnsi'))
if ea != '仿宋':
errors.append(f'Row{i}Col{j}: eastAsia={ea} (should be 仿宋)')
if ascii_f != 'Times New Roman':
errors.append(f'Row{i}Col{j}: ascii={ascii_f} (should be TNR)')
if hAnsi != 'Times New Roman':
errors.append(f'Row{i}Col{j}: hAnsi={hAnsi} (should be TNR)')
return errors
常见错误
| 错误 | 后果 | 根因 |
|---|---|---|
| ascii/hAnsi=仿宋 | 英文/数字渲染用仿宋(无西文字形,显示异常) | LLM把"统一仿宋"理解为所有属性都设仿宋 |
| 数据行无ascii/hAnsi | 英文回退系统默认字体(可能是宋体/黑体) | 只设了eastAsia,忘设西文字体 |
| 只有表头有字体 | 数据行全部回退默认 | 模板限制:只有表头行有显式字体 |
预防方案
最佳方案:修改模板文件的Normal样式或Table Grid样式定义,预设完整字体。但模板可能被多场景共用,最稳妥还是生成后强制设置。