|
@@ -0,0 +1,74 @@
|
|
|
|
+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 :
|
|
|
|
+ return None
|
|
|
|
+ # 返回结果:第二个"签字或盖章"和技术支持单位位置
|
|
|
|
+ result = []
|
|
|
|
+ if len(positions) >= 2:
|
|
|
|
+ result.append(positions[1])
|
|
|
|
+ # 第二个出现的位置(索引1)
|
|
|
|
+ elif positions is not None:
|
|
|
|
+ result.append(positions)
|
|
|
|
+
|
|
|
|
+ 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)
|