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)。

更新时间:2026-09-14 21:36:35
上一篇:Python PyPDF2合并多个PDF 一键合成教程