我的知识记录

Python在PDF指定位置插入文字:盖章签字位

用Python的PyMuPDF在PDF任意坐标插入文字,支持指定字体、字号、颜色,也能按文字搜索定位插入点,适合在合同指定位置填日期、签字、盖章编号。

场景痛点

很多合同、协议是扫描件PDF,没有表单字段,每次要在"甲方签字"、"日期"、"盖章处"后面手写或用Acrobat加文字,几十份合同签下来手都酸。用Python直接在指定坐标写字,或者搜索"签字:"两个字在它后面补内容,批量把日期、姓名填进去。

用到的库

pip install pymupdf

完整代码

# -*- coding: utf-8 -*-
"""
在 PDF 指定坐标插入文字,或搜索关键词后在其后面插入。
"""
import fitz  # PyMuPDF
from pathlib import Path


def insert_text_at_xy(pdf_path: str,
output_pdf: str,
page_no: int,
x: float,
y: float,
text: str,
fontsize: int = 12,
color=(0, 0, 0)):
"""
在指定页的 (x, y) 坐标处写文字。
坐标原点在左上角,单位 point。
"""
doc = fitz.open(pdf_path)
page = doc[page_no]

page.insert_text(
fitz.Point(x, y),
text,
fontsize=fontsize,
fontname="china-s",    # 内置简体中文
color=color,
)

doc.save(output_pdf, garbage=3, deflate=True)
doc.close()
print(f"已写入:{text} -> 第{page_no+1}页 ({x}, {y})")


def insert_text_after_keyword(pdf_path: str,
output_pdf: str,
keyword: str,
text_to_insert: str,
offset_x: float = 60,
fontsize: int = 12):
"""
搜索关键词(如"签字:"),在它右边固定距离处插入文字。
不用自己量坐标,适合模板固定的合同。
"""
doc = fitz.open(pdf_path)
hit = False

for page in doc:
rects = page.search_for(keyword)
for r in rects:
# 关键词矩形的右上角,往右偏移 offset_x
x = r.x1 + offset_x
y = r.y1 - 4   # 稍微往上对齐基线
page.insert_text(
fitz.Point(x, y),
text_to_insert,
fontsize=fontsize,
fontname="china-s",
color=(0, 0, 0),
)
hit = True
print(f"在 {keyword!r} 后写入:{text_to_insert}")

if not hit:
print(f"警告:整份文档没找到 {keyword!r}")

doc.save(output_pdf, garbage=3, deflate=True)
doc.close()


def batch_fill_signature(template_pdf: str, output_dir: str, records: list):
"""
批量:每份合同填不同的签字人和日期。
records: [{"name": "张三", "date": "2026-09-14"}, ...]
"""
out = Path(output_dir)
out.mkdir(parents=True, exist_ok=True)

for rec in records:
tmp_out = out / f"合同_{rec['name']}.pdf"
doc = fitz.open(template_pdf)
for page in doc:
# 在"甲方签字:"后写姓名
for kw, val, dx in [
("甲方签字:", rec["name"], 10),
("日期:", rec["date"], 10),
]:
rects = page.search_for(kw)
for r in rects:
page.insert_text(
fitz.Point(r.x1 + dx, r.y1 - 4),
val,
fontsize=12,
fontname="china-s",
)
doc.save(str(tmp_out), garbage=3, deflate=True)
doc.close()
print(f"生成:{tmp_out}")


if __name__ == "__main__":
# 1) 纯坐标定位
insert_text_at_xy(
"contract.pdf", "out_xy.pdf",
page_no=1, x=200, y=750,
text="张三", fontsize=14,
)

# 2) 关键词定位
insert_text_after_keyword(
"contract.pdf", "out_kw.pdf",
keyword="日期:",
text_to_insert="2026年9月14日",
)

# 3) 批量
batch_fill_signature(
template_pdf="contract.pdf",
output_dir="signed",
records=[
{"name": "张三", "date": "2026-09-14"},
{"name": "李四", "date": "2026-09-14"},
],
)

代码讲解

  • page.insert_text(point, text, ...) 在指定坐标写文字,原点在左上角,fontname="china-s"用PyMuPDF内置简体中文字体,不用额外装字体。
  • 坐标定位方式适合你已经量好位置;关键词定位方式更智能——page.search_for("日期:")返回关键词出现的矩形区域,在它右边10像素接着写,模板改动位置也不怕。
  • r.x1是关键词矩形的右边界,r.y1是下边界,文字基线一般比下边界高4像素左右(y1 - 4),这样看起来和关键词在同一行。
  • 批量函数把每份合同填不同的签字人,输出按姓名命名,方便归档。

运行结果

三个函数分别演示三种用法:坐标法在第二页指定位置写字;关键词法自动找到"日期:"后面补上日期;批量法一次生成两份签字好的合同。打开PDF检查文字位置是否对齐、有没有压到其他文字。

注意事项

  • 坐标原点在左上角,和reportlab的左下角不一样,别搞混。
  • 扫描件PDF里的"日期:"是图片里的像素,search_for搜不到文字,这种情况只能用坐标法,或者先用OCR识别。
  • china-s字体是PyMuPDF内置的,字形有限,生僻字可能缺字;需要完整中文字形用fontfile="/path/to/simsun.ttc"指定外部字体。
  • 插入的文字默认黑色,要红色盖章效果把color=(1, 0, 0)

Python在PDF指定位置插入文字:盖章签字位

标签:

更新时间:2026-09-14 21:36:35

上一篇:Python PyPDF2合并多个PDF 一键合成教程

下一篇:Python多张图片合成PDF:Pillow一键打包教程