
背景需求
师生打卡的机器要被回收了。(还好,只退了一台,这样每个园区还是有一台)
总务老师发了一个PDF,让我添加公章的PNG图片。


我之前都是在DOC或DOCX文件上,手动插入公章PNG透明背景图片,图片置于文字上方,然后保存pdf.

如果PDF插入图片,好像用Adobe Acrobat,但是我电脑没有装

解决方式






代码展示
'''
在PDF里面插入公章PNG透明图片(闵豆家园打卡机退回)
Deepseek,阿夏
20260228
'''
import fitz # PyMuPDF
import os
import glob
def insert_image_with_position(pdf_path, png_path, output_path, scale=0.5, position='custom', x=100, y=100):
"""
在PDF中插入缩放后的图片,支持多种定位方式
参数:
pdf_path: PDF文件路径
png_path: PNG图片路径
output_path: 输出PDF路径
scale: 缩放比例
position: 位置模式 ('custom', 'center', 'top-right', 'bottom-left'等)
x, y: 当position='custom'时使用的坐标
"""
try:
# 打开PDF
pdf_document = fitz.open(pdf_path)
page = pdf_document[0]
# 获取页面尺寸
page_width = page.rect.width
page_height = page.rect.height
# 打开图片
img = fitz.Pixmap(png_path)
# 计算缩放后的尺寸
new_width = int(img.width * scale)
new_height = int(img.height * scale)
print(f"页面尺寸: {page_width:.0f} x {page_height:.0f} 点")
print(f"图片尺寸: {img.width} x {img.height} 像素 -> {new_width} x {new_height} 点")
# 根据位置模式计算坐标
if position == 'center':
x = (page_width - new_width) / 2
y = (page_height - new_height) / 2
elif position == 'top-right':
x = page_width - new_width - 50 # 距离右边50点
y = page_height - new_height - 50 # 距离顶部50点
elif position == 'bottom-left':
x = 50 # 距离左边50点
y = 50 # 距离底部50点
elif position == 'bottom-right':
x = page_width - new_width - 50
y = 50
else: # custom
# 使用传入的x, y坐标
pass
print(f"插入位置: ({x:.0f}, {y:.0f})")
# 处理透明通道
if img.alpha:
img = fitz.Pixmap(fitz.csRGB, img)
# 创建图片放置的矩形区域
img_rect = fitz.Rect(x, y, x + new_width, y + new_height)
# 插入图片
page.insert_image(img_rect, pixmap=img)
# 保存
pdf_document.save(output_path)
pdf_document.close()
print("图片插入成功!")
except Exception as e:
print(f"处理失败: {e}")
# 使用示例
if __name__ == "__main__":
folder_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20260228附件2 设备回收确认单(模板)2'
pdf_files = glob.glob(os.path.join(folder_path, "*.pdf"))
png_files = glob.glob(os.path.join(folder_path, "*.png"))
if pdf_files and png_files:
# 在指定位置(100,100)插入缩小50%的图片
insert_image_with_position(
pdf_path=pdf_files[0],
png_path=png_files[0],
output_path=os.path.join(folder_path, '附件3 设备回收确认单盖章.pdf'),
scale=0.62, # 缩小50%
position='custom',
x=100,
y=375
)
因为Python制作PDF插入图片,无法手动在PDF里面移动图片的位置,所以图片的缩放比例和插入位置(XY)是无数次调整参数的结果,这个很麻烦。








反复调整参数,尽量让左侧图片和右侧图章差不多。
添加姓名:
我看到右侧服务单位经手人填写了姓名

我也给左侧的幼儿单位经手人填写总务的姓名


依旧是反复调整“姓名”的大小,位置


最后调整后的代码

'''
在PDF里面插入公章PNG透明图片和经手人姓名(闵豆家园打卡机退回)
Deepseek,阿夏
20260228
'''
import fitz # PyMuPDF
import os
import glob
def insert_image_with_position(pdf_path, png_path, output_path, scale=0.5, position='custom', x=100, y=100):
"""
在PDF中插入缩放后的图片,支持多种定位方式
"""
try:
# 打开PDF
pdf_document = fitz.open(pdf_path)
page = pdf_document[0]
# 获取页面尺寸
page_width = page.rect.width
page_height = page.rect.height
# 打开图片
img = fitz.Pixmap(png_path)
# 计算缩放后的尺寸
new_width = int(img.width * scale)
new_height = int(img.height * scale)
print(f"页面尺寸: {page_width:.0f} x {page_height:.0f} 点")
print(f"图片尺寸: {img.width} x {img.height} 像素 -> {new_width} x {new_height} 点")
# 根据位置模式计算坐标
if position == 'center':
x = (page_width - new_width) / 2
y = (page_height - new_height) / 2
elif position == 'top-right':
x = page_width - new_width - 50
y = page_height - new_height - 50
elif position == 'bottom-left':
x = 50
y = 50
elif position == 'bottom-right':
x = page_width - new_width - 50
y = 50
else: # custom
pass
print(f"插入位置: ({x:.0f}, {y:.0f})")
# 处理透明通道
if img.alpha:
img = fitz.Pixmap(fitz.csRGB, img)
# 创建图片放置的矩形区域
img_rect = fitz.Rect(x, y, x + new_width, y + new_height)
# 插入图片
page.insert_image(img_rect, pixmap=img)
# 保存
pdf_document.save(output_path)
pdf_document.close()
print("图片插入成功!")
except Exception as e:
print(f"处理失败: {e}")
def insert_chinese_text(pdf_path, output_path, text, font_size=50, x=100, y=400):
"""
在PDF中插入中文文字(使用系统字体文件)
"""
try:
# 打开PDF
pdf_document = fitz.open(pdf_path)
page = pdf_document[0]
# Windows系统宋体文件路径
# 常见的宋体文件路径
font_paths = [
r'C:\Windows\Fonts\simsun.ttc', # 宋体
r'C:\Windows\Fonts\simsun.ttf', # 宋体
r'C:\Windows\Fonts\msyh.ttc', # 微软雅黑
r'C:\Windows\Fonts\msyh.ttf', # 微软雅黑
r'C:\Windows\Fonts\SimHei.ttf', # 黑体
]
# 查找可用的字体文件
font_file = None
for fp in font_paths:
if os.path.exists(fp):
font_file = fp
print(f"找到字体文件: {font_file}")
break
if font_file is None:
# 如果没找到,尝试搜索整个Fonts目录
fonts_dir = r'C:\Windows\Fonts'
if os.path.exists(fonts_dir):
for file in os.listdir(fonts_dir):
if file.lower().startswith('sim') or file.lower().startswith('msy'):
font_file = os.path.join(fonts_dir, file)
print(f"找到可能的字体文件: {font_file}")
break
if font_file:
# 使用字体文件插入文字
# 先插入字体到PDF
font = page.insert_font(fontfile=font_file, fontname="F0")
# 插入文字
page.insert_text(
point=(x, y),
text=text,
fontsize=font_size,
fontname="F0", # 使用刚插入的字体
color=(0, 0, 0)
)
print(f"使用字体文件插入中文: {font_file}")
else:
# 如果没有找到字体文件,使用内置字体但可能无法显示中文
print("警告: 未找到中文字体文件,中文可能无法显示")
page.insert_text(
point=(x, y),
text=text,
fontsize=font_size,
fontname="helv",
color=(0, 0, 0)
)
# 保存PDF
pdf_document.save(output_path)
pdf_document.close()
print(f"文字插入成功!位置: ({x}, {y}), 字体大小: {font_size}磅")
print(f"文字内容: {text}")
except Exception as e:
print(f"插入文字失败: {e}")
if 'pdf_document' in locals():
pdf_document.close()
raise
# 使用示例
if __name__ == "__main__":
folder_path = r'C:\Users\jg2yXRZ\OneDrive\桌面\20260228附件2 设备回收确认单(模板)2'
pdf_files = glob.glob(os.path.join(folder_path, "*.pdf"))
png_files = glob.glob(os.path.join(folder_path, "*.png"))
if pdf_files and png_files:
# 输出文件名
output_pdf = os.path.join(folder_path, '附件3 设备回收确认单盖章签字.pdf')
# 第一步:插入图片
print("=" * 50)
print("步骤1: 插入图片")
temp_pdf = os.path.join(folder_path, 'temp_with_image.pdf')
insert_image_with_position(
pdf_path=pdf_files[0],
png_path=png_files[0],
output_path=temp_pdf,
scale=0.62,
position='custom',
x=100,
y=375
)
# 第二步:插入中文文字
print("=" * 50)
print("步骤2: 插入中文文字")
insert_chinese_text(
pdf_path=temp_pdf,
output_path=output_pdf,
text="张三",
font_size=14,
x=150,
y=540 )
# 清理临时文件
if os.path.exists(temp_pdf):
os.remove(temp_pdf)
print(f"临时文件已清理: {temp_pdf}")
print("=" * 50)
print(f"处理完成!最终文件: {output_pdf}")
else:
print("未找到PDF或PNG文件")

