# -*- coding: utf-8 -*- """把业绩证明材料渲染成可插入 Word 的 JPEG。 包含三类: 合同关键页 询比文件要求的首页、服务内容页、金额页、签字盖章页 结算发票 电子专票 PDF 单页;DOC2024-001 为 4 张纸质专票扫描件 查验截图 税务系统发票详情截图(现仅业绩3 的 4 张纸质专票有) 扫描件按 150dpi 出图后转 JPEG,兼顾可读性与文件体积。 """ import io import os import shutil import sys import zipfile import fitz from PIL import Image sys.stdout = io.TextIOWrapper(sys.stdout.buffer, encoding="utf-8") HERE = os.path.dirname(os.path.abspath(__file__)) MAT = (r"C:\Users\skygu\OneDrive\Projects\AIDOP\项目\项目招投标\相关准备材料") CON = os.path.join(MAT, "过往业绩合同") INV = os.path.join(CON, "发票") OUT = os.path.join(HERE, "_bid_assets", "perf") DPI, Q = 150, 85 # 业绩序号 → (合同文件, 关键页页码[首页/服务内容/金额/签字盖章]) CONTRACTS = [ (1, "DOC2025003.pdf", [1, 2, 3, 5]), (2, "DOC2024004.pdf", [1, 2, 3, 8]), (3, "DOC2024-001.pdf", [1, 2, 3, 8]), (4, "DOC2024003.pdf", [1, 2, 3, 8]), (5, "DOC2025002.pdf", [1, 2, 3, 8]), ] # 业绩序号 → 电子发票文件名(业绩3 为纸质专票,另行处理) EINV = { 1: "dzfp_26112000002914765426_河南产业互联网联合发展有限公司_20260804170557.pdf", 2: "dzfp_24112000000220367465_智盛易(天津)科技有限公司_20260804170417.pdf", 4: "dzfp_24112000000142493545_智盛易(天津)科技有限公司_20260804170418.pdf", 5: "dzfp_25112000000135255646_智盛易(天津)科技有限公司_20260804170514.pdf", } MAXW = 1700 # 插入宽度约 14cm,再高的像素只会白占体积 def save(pix_or_im, name): im = pix_or_im if not isinstance(im, Image.Image): im = Image.frombytes("RGB", (im.width, im.height), im.samples) if im.mode != "RGB": im = im.convert("RGB") if im.width > MAXW: im = im.resize((MAXW, round(im.height * MAXW / im.width)), Image.LANCZOS) p = os.path.join(OUT, name) im.save(p, "JPEG", quality=Q, subsampling=0, optimize=True) print(f" {name:<34} {im.width}×{im.height} {os.path.getsize(p) / 1024:6.0f}KB") return p def pdf_page(path, page, name): d = fitz.open(path) pix = d[page - 1].get_pixmap(dpi=DPI) p = save(pix, name) d.close() return p def main(): if os.path.exists(OUT): shutil.rmtree(OUT) os.makedirs(OUT) total = 0 print("合同关键页") tags = ["首页", "服务内容页", "金额页", "签字盖章页"] for no, fn, pages in CONTRACTS: for tag, pg in zip(tags, pages): pdf_page(os.path.join(CON, fn), pg, f"c{no}_{tag}.jpg") total += 1 print("\n电子发票") for no, fn in sorted(EINV.items()): src = os.path.join(INV, fn) if not os.path.exists(src): # 24/25 年两批是压缩包内的 src = find_in_zip(fn) pdf_page(src, 1, f"i{no}_发票.jpg") total += 1 print("\n业绩3 纸质专票(4 张)") d = fitz.open(os.path.join(INV, "北京增值税专用发票.pdf")) for i in range(d.page_count): save(d[i].get_pixmap(dpi=DPI), f"i3_发票{i + 1}.jpg") total += 1 d.close() print("\n税务系统查验截图(业绩3 的 4 张专票)") pngs = sorted(n for n in os.listdir(INV) if n.endswith(".png")) for i, n in enumerate(pngs, 1): save(Image.open(os.path.join(INV, n)), f"v3_查验{i}.jpg") total += 1 print("\n劳动合同(8 页)") d = fitz.open(os.path.join(MAT, "DOC劳动合同.pdf")) for i in range(d.page_count): save(d[i].get_pixmap(dpi=DPI), f"lab_p{i + 1}.jpg") total += 1 d.close() mb = sum(os.path.getsize(os.path.join(OUT, f)) for f in os.listdir(OUT)) / 1024 / 1024 print(f"\n共 {total} 张,合计 {mb:.1f}MB → {OUT}") def find_in_zip(fn): """两批电子发票在 zip 里,解到临时目录后返回路径。""" tmp = os.path.join(HERE, "_tmp_inv") for root, _, files in os.walk(tmp): if fn in files: return os.path.join(root, fn) for z in (n for n in os.listdir(INV) if n.endswith(".zip")): with zipfile.ZipFile(os.path.join(INV, z)) as zf: for info in zf.infolist(): try: nm = info.filename.encode("cp437").decode("gbk") except Exception: nm = info.filename if nm == fn: os.makedirs(tmp, exist_ok=True) dst = os.path.join(tmp, fn) with zf.open(info) as s, open(dst, "wb") as t: t.write(s.read()) return dst raise FileNotFoundError(fn) if __name__ == "__main__": main()