import io import tempfile from reportlab.lib.pagesizes import A4 import pdfplumber from PyPDF2 import PdfReader, PdfWriter from reportlab.pdfgen import canvas from PIL import Image import logging # 配置日志 logging.basicConfig(level=logging.INFO) logger = logging.getLogger(__name__) def find_signature_positions(pdf_path, target_texts=["签字或盖章", "技术支持单位(盖章)"]): """查找所有签名位置""" positions = [] with pdfplumber.open(pdf_path) as pdf: for i, page in enumerate(pdf.pages): for word in page.extract_words(): for target in target_texts: if target in word["text"]: x, y = word["x0"], word["top"] positions.append((i, x, y, target)) logger.info(f"找到签名位置: 第{i}页, {target} at ({x}, {y})") # 返回结果:所有"签字或盖章"和"技术支持单位(盖章)"的位置 if len(positions) == 0 or positions == []: return None # 返回结果:第二个"签字或盖章"和技术支持单位位置 result = [] if len(positions) >= 2: result.append(positions[1]) # 第二个出现的位置(索引1) else: result.append(positions[0]) return result def add_signature_to_pdf(input_pdf, output_pdf, signature_img, positions, offset_x=30, offset_y=-10): """添加签名到PDF""" reader = PdfReader(input_pdf) writer = PdfWriter() a4_width, a4_height = A4 # (595.2, 841.68) for page_index in range(len(reader.pages)): page = reader.pages[page_index] for pos in positions: if pos[0] == page_index: packet = io.BytesIO() can = canvas.Canvas(packet, pagesize=A4) img = Image.open(signature_img) img_width, img_height = img.size aspect_ratio = img_height / img_width new_width = 43 * (72 / 25.4) # 40mm ≈ 113.39点 new_height = new_width * aspect_ratio x, y = pos[1], a4_height - pos[2] if pos[3] == "技术支持单位(盖章)": y = y - new_height / 2 else: y = y - new_height / 3 * 2 x = max(0, min(x, a4_width - new_width)) y = max(0, min(y, a4_height - new_height)) can.drawImage(signature_img, x, y, width=new_width, height=new_height, mask='auto') can.save() packet.seek(0) overlay_pdf = PdfReader(packet) page.merge_page(overlay_pdf.pages[0]) writer.add_page(page) with open(output_pdf, "wb") as f: writer.write(f)