# -*- coding: utf-8 -*- """校验盖章版:与原件逐段比对文字,并渲染有章的页面便于目视确认。""" import io import os import sys import time from docx import Document sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") HERE = os.path.dirname(os.path.abspath(__file__)) BID = r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目招投标" NAME = "响应文件(完整版)-2026年河南产互联制造业数据智能运营平台研发项目.docx" SRC = os.path.join(BID, NAME) OUT = os.path.join(BID, NAME[:-5] + "(已签章).docx") PDF = os.path.join(HERE, "_tmp_inspect", "sealed.pdf") DIR = os.path.join(HERE, "_tmp_inspect") os.makedirs(DIR, exist_ok=True) PAGES = [1, 5, 6, 7, 8, 9, 12, 46, 61, 62, 65, 76, 79, 91] def compare(): a, b = Document(SRC), Document(OUT) pa = [p.text for p in a.paragraphs] pb = [p.text for p in b.paragraphs] print(f"段落数:原件 {len(pa)} 盖章版 {len(pb)}") diff = 0 for i, (x, y) in enumerate(zip(pa, pb)): if x != y: diff += 1 if diff <= 8: print(f" × P{i}\n 原「{x[:56]}」\n 章「{y[:56]}」") print(f"段落文字差异 {diff} 处") ta = [c.text for t in a.tables for r in t.rows for c in r.cells] tb = [c.text for t in b.tables for r in t.rows for c in r.cells] print(f"表格数:原件 {len(a.tables)} 盖章版 {len(b.tables)};" f"单元格 {len(ta)} / {len(tb)}," f"文字差异 {sum(1 for x, y in zip(ta, tb) if x != y)} 处") ia = len(a.inline_shapes) ib = len(b.inline_shapes) print(f"嵌入式图片:原件 {ia} 盖章版 {ib}(应相等,印章走浮动图形)") def export(): import win32com.client as win32 word = None for i in range(4): try: word = win32.gencache.EnsureDispatch("Word.Application") word.Visible = False word.DisplayAlerts = 0 break except Exception as e: print(f" 重试 {i + 1}/4:{e}") time.sleep(4) doc = word.Documents.Open(OUT, ReadOnly=True) try: print(f"浮动图形数:{doc.Shapes.Count}") doc.ExportAsFixedFormat(PDF, 17) finally: doc.Close(False) word.Quit() print(f"导出 {PDF} {os.path.getsize(PDF) / 1024 / 1024:.1f}MB") compare() if not os.path.exists(PDF) or "--re" in sys.argv: export() import fitz d = fitz.open(PDF) print(f"\nPDF 共 {d.page_count} 页,渲染 {PAGES}") for p in PAGES: if p <= d.page_count: d[p - 1].get_pixmap(dpi=100).save(os.path.join(DIR, f"s{p:03d}.png")) print("完成") d.close()