背景
昨天收到的新需求,一份文件从其他部门发起,进行一些文字填写后盖章,再到我们部门,我们接收到的是pdf文件,所以需要在pdf文件中进行修改,插入当日日期等文字。但有要求字体必须和原文档字体相同。
问题代码
开始时通过fontfile传本地文件夹中的指定字体包,但是无论怎么修改最终在pdf中插入的文字格式都是PyMuPDF的默认Helvetica字体。
inserter = SmartDateInserterV6(fontfile="./fonts/fangsongGB2312.ttf", fontsize=16)
def _insert_before(self, page, span, text, offset_x, offset_y):
x, y = span["bbox"][:2]
rgb = int_to_rgb_tuple(span.get("color", 0))
page.insert_text(
(x - offset_x, y + offset_y),
text,
fontfile=self.fontfile,
fontsize=self.fontsize,
color=rgb
)

如上图所示
根本原因
page.insert_text() 在没有显式 fontname 参数时会把字体名默认为 "Helv" / "Helvetica"。
"Helv" 属于 PDF 的 Base‑14 保留字体名。只要传入的 fontname 是保留名,PyMuPDF 就 忽略 fontfile / fontbuffer 参数,直接调用内置 Helvetica,所以看到的始终是 Helvetica,而不是自己的仿宋字体。
解决办法
解决办法一:在 insert_text 时同时指定 自定义 fontname
page.insert_text(
(x - offset_x, y + offset_y),
text,
fontfile=self.fontfile,
fontsize=self.fontsize,
color=rgb,
fontname="FangSongGB" # 避免 Helv
)
只要 fontname 不是保留名,PyMuPDF 就会把 fontfile 嵌入 PDF,并真正使用你的仿宋字体。
解决办法二:先把字体注册到页面,再写入文本
import fitz
doc = fitz.open()
page = doc.new_page()
font_path = "./fonts/fangsongGB2312.ttf"
# 1️⃣ 先把字体嵌入并得到 xref
xref = page.insert_font(fontname="FangSongGB", fontfile=font_path)
# 2️⃣ 写文本时只需要给出 fontname
page.insert_text(
(100, 100),
"测试 2025 年",
fontname = "FangSongGB",
fontsize = 20
)
doc.save("test_font.pdf")
doc.close()
我使用方法一,最终效果如图