在FPDF中无法添加NotoSansJP等字体?AWS Lambda Python问题
问题分析与解决方案
问题背景
在AWS Lambda的Python 3.12环境中,尝试根据指定语言加载对应Noto字体生成PDF页面时,调用pdf.add_font()抛出'head'错误,但使用DejaVu字体的原始方法可正常运行。TTF字体文件已放置在根目录,日语、韩语、俄语场景均触发该错误。
原可正常运行代码
# This works 100% def add_new_page(): pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True) pdf.set_font('DejaVu', size=12) pdf.add_page() print('Adding new page')
修改后报错的代码
def add_new_page(Language:str): try: match Language.lower(): case "japanese": print(f"Adding {Language.lower()} language to PDF") pdf.add_font('NotoCJK', '', 'NotoSansJP-VariableFont_wght.ttf', uni=True) pdf.set_font('NotoCJK', size=12) case "korean": print(f"Adding {Language.lower()} language to PDF") pdf.add_font('NotoCJK', '', 'NotoSansKR-VariableFont_wght.ttf', uni=True) pdf.set_font('NotoCJK', size=12) case _: print(f"Adding {Language.lower()} language to PDF") pdf.add_font('NotoSans', '', 'NotoSans-VariableFont_wdth,wght.ttf', uni=True) pdf.set_font('NotoSans', size=12) except Exception as e: print(f"Error adding font: {e}") # Prints => Error adding font: 'head' pdf.add_font('DejaVu', '', 'DejaVuSansCondensed.ttf', uni=True) pdf.set_font('DejaVu', size=12) pdf.add_page() print('Adding new page')
错误原因
'head'错误的核心原因是你使用的PDF库(如FPDF/fpdf2)对可变字体(Variable Font)的解析存在兼容性问题。DejaVu是静态字体,格式简单易解析;而你下载的Noto字体是可变字体(文件名包含VariableFont),这类字体的内部结构更复杂,部分PDF库版本对其支持不完善,尤其在AWS Lambda的受限环境中更容易触发解析错误。
解决方案
1. 替换为静态Noto字体
下载对应语言的静态字体版本(而非可变字体),例如:
- 日语:
NotoSansJP-Regular.ttf - 韩语:
NotoSansKR-Regular.ttf - 俄语:
NotoSans-Regular.ttf
将这些静态字体文件替换根目录中的可变字体文件,然后修改代码中的字体文件名即可。
2. 确认Lambda环境中的字体路径
AWS Lambda执行时的工作目录可能并非你预期的根目录,建议使用绝对路径加载字体,避免路径问题:
import os # 获取当前工作目录 current_dir = os.getcwd() # 拼接字体文件绝对路径 font_file = os.path.join(current_dir, "NotoSansJP-Regular.ttf") pdf.add_font('NotoCJK', '', font_file, uni=True)
3. 升级PDF库版本
如果你使用的是fpdf2,升级到最新版本可提升对可变字体的支持(若你坚持使用可变字体):
pip install --upgrade fpdf2
注意部署Lambda时需包含升级后的依赖包。
4. 优化异常处理逻辑
确保字体设置完成后再执行pdf.add_page(),避免因字体未正确加载导致后续PDF生成异常。
修改后的示例代码
import os def add_new_page(Language:str): try: current_dir = os.getcwd() match Language.lower(): case "japanese": print(f"Adding {Language.lower()} language to PDF") font_file = os.path.join(current_dir, "NotoSansJP-Regular.ttf") pdf.add_font('NotoCJK', '', font_file, uni=True) pdf.set_font('NotoCJK', size=12) case "korean": print(f"Adding {Language.lower()} language to PDF") font_file = os.path.join(current_dir, "NotoSansKR-Regular.ttf") pdf.add_font('NotoCJK', '', font_file, uni=True) pdf.set_font('NotoCJK', size=12) case "russian": print(f"Adding {Language.lower()} language to PDF") font_file = os.path.join(current_dir, "NotoSans-Regular.ttf") pdf.add_font('NotoSans', '', font_file, uni=True) pdf.set_font('NotoSans', size=12) case _: print(f"Adding {Language.lower()} language to PDF") font_file = os.path.join(current_dir, "NotoSans-Regular.ttf") pdf.add_font('NotoSans', '', font_file, uni=True) pdf.set_font('NotoSans', size=12) except Exception as e: print(f"Error adding font: {e}") # 回退到DejaVu字体 font_file = os.path.join(current_dir, "DejaVuSansCondensed.ttf") pdf.add_font('DejaVu', '', font_file, uni=True) pdf.set_font('DejaVu', size=12) pdf.add_page() print('Adding new page')
内容的提问来源于stack exchange,提问作者Alfa Rojo
相关产品推荐
相关产品推荐

