如何为已有PDF文件添加自定义字体?代码运行异常求助
解决自定义字体嵌入PDF的问题
原代码的问题分析
- 导入错误:你使用的是
fpdf2库,但代码里导入了旧版的fpdf.FPDF,两者API存在差异,会导致字体添加失败。 - 逻辑偏差:原代码只是生成一个带自定义字体文本的新页面,再合并到原PDF首页,这只是叠加了文本,并没有真正将字体嵌入到原PDF文档中供全局使用。
方案1:在原PDF中添加带自定义字体的文本(嵌入字体)
修正代码,使用fpdf2的正确API,确保字体嵌入并保留原PDF内容:
from pypdf import PdfReader, PdfWriter import io from fpdf2 import FPDF # 1. 用fpdf2生成带自定义字体和文本的PDF packet = io.BytesIO() pdf = FPDF() pdf.add_page() # 添加自定义字体,fpdf2对OTF字体需指定type='TrueType'以兼容处理 pdf.add_font('myfont', '', 'myfont.otf', uni=True, type='TrueType') pdf.set_font('myfont', '', 12) # 在指定坐标添加自定义字体文本 pdf.text(x=10, y=10, txt="Hello, 自定义字体测试!") pdf.output(packet) packet.seek(0) # 2. 读取原PDF和生成的PDF existing_pdf = PdfReader(open("target.pdf", "rb")) new_pdf = PdfReader(packet) output = PdfWriter() # 3. 合并页面:将带字体的内容叠加到原PDF第一页(如需处理所有页可循环遍历) page = existing_pdf.pages[0] page.merge_page(new_pdf.pages[0]) output.add_page(page) # 处理所有页面的写法: # for page_num in range(len(existing_pdf.pages)): # page = existing_pdf.pages[page_num] # page.merge_page(new_pdf.pages[0]) # output.add_page(page) # 4. 保存输出文件 with open("new_target.pdf", "wb") as outputStream: output.write(outputStream)
方案2:将自定义字体嵌入原PDF(替换现有字体)
如果需求是把自定义字体嵌入原PDF,替换文档中已有的未嵌入字体,可使用pypdf的底层字体操作:
from pypdf import PdfReader, PdfWriter from pypdf.generic import NameObject, DictionaryObject, BytesObject reader = PdfReader("target.pdf") writer = PdfWriter() # 读取自定义字体文件 with open("myfont.otf", "rb") as font_file: font_data = font_file.read() # 遍历所有页面嵌入字体 for page in reader.pages: # 初始化页面资源字典 if "/Resources" not in page: page["/Resources"] = DictionaryObject() resources = page["/Resources"] if "/Font" not in resources: resources["/Font"] = DictionaryObject() fonts = resources["/Font"] # 定义字体描述符,嵌入字体数据 font_descriptor = DictionaryObject() font_descriptor["/FontName"] = NameObject("/myfont") font_descriptor["/FontFile2"] = BytesObject(font_data) font_descriptor["/Flags"] = 32 # 标记为嵌入子集 # 创建新字体字典 new_font = DictionaryObject() new_font["/Type"] = NameObject("/Font") new_font["/Subtype"] = NameObject("/TrueType") new_font["/BaseFont"] = NameObject("/myfont") new_font["/FontDescriptor"] = font_descriptor # 替换原PDF中的目标字体(需替换为实际字体名称,如/F1,可通过PDF阅读器属性查看) fonts["/F1"] = new_font writer.add_page(page) # 保存最终文件 with open("new_target_with_font.pdf", "wb") as out_file: writer.write(out_file)
注意事项
- 确保
myfont.otf文件路径正确,可使用绝对路径避免找不到文件。 - 替换现有字体时,需先通过PDF阅读器查看原文档的字体名称,再修改代码中的对应键值(如示例中的
/F1)。
内容的提问来源于stack exchange,提问作者HaituN
相关产品推荐
相关产品推荐

