# -*- coding: utf-8 -*- """对比 S1 与本次修改文档的封面细节、图片数量与标题结构差异。""" from __future__ import annotations import zipfile from pathlib import Path from docx import Document BASE = Path(r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目管理\产互联项目管理\交付文档\Release产互联") MINE = BASE / "待确认" S1 = [ "S1产销协同业务需求描述-V0.4.docx", "S1产销协同模块蓝图设计方案-V2.2.docx", "S1产销协同模块详细设计说明书-V1.2.docx", "S1产销协同模块用户操作手册-V1.2.docx", ] MINE_DOCS = [ "系统集成业务需求描述-V0.5.docx", "系统集成模块蓝图设计方案-V0.5.docx", "系统集成模块详细设计说明书-V0.5.docx", "运营改善业务需求描述-V0.5.docx", "运营改善模块蓝图设计方案-V0.5.docx", "运营改善模块详细设计说明书-V0.5.docx", "九宫格智慧运营看板模块详细设计说明书-V0.1.docx", ] def img_count(path: Path) -> int: with zipfile.ZipFile(path) as z: return len([n for n in z.namelist() if n.startswith("word/media/")]) def headings_of(d: Document): out = [] for p in d.paragraphs: s = p.style.name if s.startswith(("Heading", "标题")) and p.text.strip(): out.append(f"[{s}] {p.text.strip()}") return out def cover_info(d: Document, n=12): out = [] for p in d.paragraphs[:n]: if p.text.strip(): f = None for r in p.runs: if r.text.strip(): f = r.font break sz = f.size.pt if f and f.size else None out.append(f" ({f.name if f else '-'}/{sz}/b={f.bold if f else '-'}) {p.text.strip()}") return out def dump(path: Path, show_heads: bool = True, head_limit: int = 100): d = Document(str(path)) print(f"\n{'='*66}\n{path.name} imgs={img_count(path)} tables={len(d.tables)}") print("-- 封面段落 --") print("\n".join(cover_info(d))) if d.tables: t = d.tables[0] print(f"-- 首表 {len(t.rows)}行 --") for r in t.rows[:3]: print(" | " + " | ".join(c.text.strip().replace("\n", "/") for c in r.cells)) if show_heads: hs = headings_of(d) print(f"-- 标题 {len(hs)} 个 --") print("\n".join(" " + h for h in hs[:head_limit])) def main(): print("########## S1 基线 ##########") for name in S1: dump(BASE / name, show_heads=False) print("\n\n########## 本次修改的文档 ##########") for name in MINE_DOCS: dump(MINE / name, show_heads=True) if __name__ == "__main__": main()