# 用同案件已有 docx 作母版生成"全新文书"——页眉/边框继承陷阱 ## 场景 同一案件已有一份成稿文书(如检察监督申请书 v9),需要再做一份**不同类型**的全新文书(如给法院的《情况反映》)。为保证字体、字号、行距、页边距、样式与申请书**同源**,最稳的做法是:把申请书 docx 当母版,克隆它的段落模板(标题段/正文段/落款段/附件段的 pPr+rPr),清空 body 后用模板段重建全文。 > ⚠️ 这套手法适用于**任何"用 A 文书作母版生成 B 文书"**,不限于《情况反映》。2026-06-25 郭同学案再次踩中:用万禹案**再审申请书**作母版生成**答辩状**,header2.xml 原样继承了"申 请 人:上海万禹实业… / 再审申请书 / 生效判决案号:(2025)沪01民终15828号"——OnlyOffice 渲染第 1 页页眉赫然是别案的当事人和案号。清空页眉法(见下)验证有效:删 header2.xml 所有 run、重新打包后页眉纯净。**判别哪个 header 文件有文字**:遍历 `word/header*.xml`,读各自 `w:t` 拼出文字,非空的那个才是要清的(母版常有 header1/2/3 三个,只有一个带内容)。 这套"克隆段落模板 + 替换 body"的手法对**正文**是对的、省心,但有一个隐蔽的坑: ## 坑:header/footer 和 pBdr 横线会原样继承,且常常张冠李戴 - 替换 `word/document.xml` 的 body 只动了正文。**`word/header1.xml`、`word/footer1.xml` 原封不动**被继承。 - 实测(2026-06-23 邹家案):申请书 v9 的 header1.xml 写的是"**申请人(被告)… / 申请监督民事诉讼案号:… / 受理法院:…**"——这是**检察监督申请书的页眉**。套到《情况反映》(受文机关是法院本身)上,称谓完全错配("申请监督""受理法院"对法院内部监督渠道不成立)。 - 更隐蔽的是**页眉横线**:清掉页眉文字后,OnlyOffice 渲染里页面顶端仍残留一条贯穿左右的黑线。它不是文字,是页眉段落 `pPr` 里的**段落下边框 ``**(页眉样式自带)。只删 run 文字删不掉它。 ## 交付前必查(母版法专用三查) 凡是"用 A 文书作母版生成 B 文书",OnlyOffice 渲染后**必须逐页看页眉页脚**,确认: 1. 页眉文字是否属于 B 文书的类型(不是 A 残留的称谓/案号格式); 2. 页眉/页脚有无 A 残留的横线、单位名、修订标识; 3. 落款受文机关、抬头与 B 的收件对象一致。 vision 看第 1 页时,把"页眉区域内容"作为独立一项问出来——它最容易被正文的整洁掩盖过去。 ## 修法(清空页眉 + 去横线) 默认推荐**清空页眉**(内部反映材料正文已含案号当事人,页眉非必需,留空最干净不会错配)。纯 zipfile+lxml: ```python import zipfile, io from lxml import etree W='http://schemas.openxmlformats.org/wordprocessingml/2006/main' def w(t): return f'{{{W}}}{t}' zin = zipfile.ZipFile(src) h = etree.fromstring(zin.read('word/header1.xml')) # 1) 清空页眉所有 run 文字(保留空段结构,别删整段——破坏 schema) for p in list(h.iter(w('p'))): for r in list(p.findall(w('r'))): p.remove(r) # 2) 删 pBdr(横线的真正来源)——只删文字删不掉这条线 for ppr in h.iter(w('pPr')): pBdr = ppr.find(w('pBdr')) if pBdr is not None: ppr.remove(pBdr) # 3) 去掉 pStyle 引用(页眉样式常自带下边框,连根拔) for ppr in h.iter(w('pPr')): ps = ppr.find(w('pStyle')) if ps is not None: ppr.remove(ps) new_h = etree.tostring(h, xml_declaration=True, encoding='UTF-8', standalone=True) buf = io.BytesIO() with zipfile.ZipFile(buf, 'w', zipfile.ZIP_DEFLATED) as zo: for n in zin.namelist(): d = zin.read(n) if n == 'word/header1.xml': d = new_h zo.writestr(n, d) open(src, 'wb').write(buf.getvalue()) ``` 若要**保留页眉但改成中性表述**(方案 B),把 run 文字替换成"案号:(…)… / 反映人:…"这类不带"申请监督""受理法院"的中性字段即可——但默认先问用户走 A 还是 B,别擅自保留错配页眉。 ## 关掉修订模式(全新文书非修订态) 母版若是修订态(settings.xml 带 ``),生成全新文书时要去掉它——新文书是全新成稿不是改稿,不该带修订痕迹: ```python if n == 'word/settings.xml': s = etree.fromstring(d) tr = s.find(w('trackRevisions')) if tr is not None: s.remove(tr) d = etree.tostring(s, xml_declaration=True, encoding='UTF-8', standalone=True) ``` ## 段落模板克隆要点(正文部分,已验证可用) - 从母版抽各类型段落各一个作模板:标题(居中 bold sz30)、正文(首行缩进 fl480 sz24)、受文机关(顶格 bold sz24)、落款(右对齐 sz24)、附件标题(顶格 bold sz24)、附件项(fl480 sz24)。 - `mk()` 构造段落时:深拷贝模板段 → 删掉模板里的旧 run/ins/del → 删 numPr(避免继承自动编号)→ 强制字体(eastAsia=仿宋、ascii/hAnsi=Times New Roman)→ 按需 set/unset bold → 塞入新文字 run(`t.set('{http://www.w3.org/XML/1998/namespace}space','preserve')`)。 - 顶格段(受文机关、"丽水市…法院:")用 `no_indent=True` 删掉 ind,否则继承首行缩进会缩进两格。 - body 清空后把新段 `insert` 到 `sectPr` 之前(sectPr 必须保留在 body 末尾,决定页面尺寸/页边距)。 - 字体属性交付前用 zipfile 逐 run 统计核验:CJK 全仿宋、LATIN 全 Times New Roman,0 回退。