You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为已有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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.25 09:13:26