add_signature.py 2.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374
  1. import io
  2. import tempfile
  3. from reportlab.lib.pagesizes import A4
  4. import pdfplumber
  5. from PyPDF2 import PdfReader, PdfWriter
  6. from reportlab.pdfgen import canvas
  7. from PIL import Image
  8. import logging
  9. # 配置日志
  10. logging.basicConfig(level=logging.INFO)
  11. logger = logging.getLogger(__name__)
  12. def find_signature_positions(pdf_path, target_texts=["签字或盖章", "技术支持单位(盖章)"]):
  13. """查找所有签名位置"""
  14. positions = []
  15. with pdfplumber.open(pdf_path) as pdf:
  16. for i, page in enumerate(pdf.pages):
  17. for word in page.extract_words():
  18. for target in target_texts:
  19. if target in word["text"]:
  20. x, y = word["x0"], word["top"]
  21. positions.append((i, x, y, target))
  22. logger.info(f"找到签名位置: 第{i}页, {target} at ({x}, {y})")
  23. # 返回结果:所有"签字或盖章"和"技术支持单位(盖章)"的位置
  24. if len(positions) == 0 :
  25. return None
  26. # 返回结果:第二个"签字或盖章"和技术支持单位位置
  27. result = []
  28. if len(positions) >= 2:
  29. result.append(positions[1])
  30. # 第二个出现的位置(索引1)
  31. elif positions is not None:
  32. result.append(positions)
  33. return result
  34. def add_signature_to_pdf(input_pdf, output_pdf, signature_img, positions, offset_x=30, offset_y=-10):
  35. """添加签名到PDF"""
  36. reader = PdfReader(input_pdf)
  37. writer = PdfWriter()
  38. a4_width, a4_height = A4 # (595.2, 841.68)
  39. for page_index in range(len(reader.pages)):
  40. page = reader.pages[page_index]
  41. for pos in positions:
  42. if pos[0] == page_index:
  43. packet = io.BytesIO()
  44. can = canvas.Canvas(packet, pagesize=A4)
  45. img = Image.open(signature_img)
  46. img_width, img_height = img.size
  47. aspect_ratio = img_height / img_width
  48. new_width = 43 * (72 / 25.4) # 40mm ≈ 113.39点
  49. new_height = new_width * aspect_ratio
  50. x, y = pos[1], a4_height - pos[2]
  51. if pos[3] == "技术支持单位(盖章)":
  52. y = y - new_height / 2
  53. else:
  54. y = y - new_height / 3 * 2
  55. x = max(0, min(x, a4_width - new_width))
  56. y = max(0, min(y, a4_height - new_height))
  57. can.drawImage(signature_img, x, y, width=new_width, height=new_height, mask='auto')
  58. can.save()
  59. packet.seek(0)
  60. overlay_pdf = PdfReader(packet)
  61. page.merge_page(overlay_pdf.pages[0])
  62. writer.add_page(page)
  63. with open(output_pdf, "wb") as f:
  64. writer.write(f)