| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- # -*- 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()
|