PyMuPDF插入文字时本地字体配置无效仍使用默认字体问题

笔记哥 / 04-16 / 44点赞 / 0评论 / 552阅读
## 背景 昨天收到的新需求,一份文件从其他部门发起,进行一些文字填写后盖章,再到我们部门,我们接收到的是pdf文件,所以需要在pdf文件中进行修改,插入当日日期等文字。但有要求字体必须和原文档字体相同。 ## 问题代码 开始时通过fontfile传本地文件夹中的指定字体包,但是无论怎么修改最终在pdf中插入的文字格式都是PyMuPDF的默认Helvetica字体。 ```csharp inserter = SmartDateInserterV6(fontfile="./fonts/fangsongGB2312.ttf", fontsize=16) ``` ```csharp 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 ) ``` ![](https://cdn.res.knowhub.vip/c/2504/16/88fa8aaa.png?G1cAAMTP0x8n7ucRtlGHaxNFQjNgkUZQKWG93nv3aUTf78qa4jP7WH4%2b%2fKaP5aRFYCikrOCEECRLBthUOEhmWLWEGvd0) 如上图所示 ## 根本原因 page.insert\_text() 在没有显式 fontname 参数时会把字体名默认为 "Helv" / "Helvetica"。 “Helv” 属于 PDF 的 Base‑14 保留字体名。只要传入的 fontname 是保留名,PyMuPDF 就 忽略 fontfile / fontbuffer 参数,直接调用内置 Helvetica,所以看到的始终是 Helvetica,而不是自己的仿宋字体。 ## 解决办法 解决办法一:在 insert\_text 时同时指定 自定义 fontname ```csharp 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,并真正使用你的仿宋字体。 解决办法二:先把字体注册到页面,再写入文本 ```csharp 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() ``` 我使用方法一,最终效果如图 ![](https://cdn.res.knowhub.vip/c/2504/16/f25bb33a.png?G1cAAETn9LwUqCDZvtMdbIlTE20GLNIIKiWs13vO2jfR9wcYmp%2fR%2boz94TetzyC4WDEnMIwVKUgVZxOpXhL4UlgxRV4jAA%3d%3d)