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

Django应用中使用WeasyPrint渲染PDF时自定义字体无法加载

解决WeasyPrint在Django中无法加载自定义字体的问题

问题描述

生成PDF时出现错误:

fonts/add_font_face - Font-face 'Playfair Display' cannot be loaded

项目目录结构:

- project
  - manage.py
  - ...
  - gallery
    - static
      - files  # 注意:模板中引用的是fonts目录,此处可能存在目录名不一致问题
    - views.py
    - url.py
    - ...

生成PDF的代码:

base_url = request.build_absolute_uri("/")
HTML(string=template, base_url=base_url).write_pdf(output)

模板中的@font-face定义:

@font-face {
  font-family: 'Playfair Display';
  font-weight: normal;
  src: url({% static 'fonts/PlayfairDisplay-Regular.ttf' %}) format("truetype");
}

解决建议

1. 核对静态文件目录与路径

  • 检查gallery/static下是否存在fonts目录:当前目录结构显示的是static/files,与模板中引用的fonts目录不匹配,这很可能是核心问题。如果是目录名写错,将files重命名为fonts,或者调整模板中的路径为files/PlayfairDisplay-Regular.ttf。
  • 执行python manage.py collectstatic:确保静态文件被收集到Django配置的STATIC_ROOT目录下,WeasyPrint在访问静态资源时通常依赖收集后的文件(尤其是生产环境)。

2. 优化base_url参数配置

  • 替换base_url为静态文件的绝对根路径:
    from django.conf import settings
    base_url = request.build_absolute_uri(settings.STATIC_URL)
    
    这样WeasyPrint能更精准地解析static标签生成的相对路径。
  • 或者直接在模板中生成绝对路径:
    修改@font-face的src为绝对URL,无需依赖base_url:
    src: url("{{ request.build_absolute_uri('/static/fonts/PlayfairDisplay-Regular.ttf') }}") format("truetype");
    

3. 直接使用本地文件路径加载字体

绕过静态文件服务,直接传入字体文件的本地绝对路径给WeasyPrint:

  • 在视图中拼接字体文件的本地路径:
    import os
    from django.conf import settings
    font_path = os.path.join(settings.STATICFILES_DIRS[0], 'fonts', 'PlayfairDisplay-Regular.ttf')
    
  • 将该路径传入模板上下文,在@font-face中使用:
    src: url("file://{{ font_path }}") format("truetype");
    
    注意:file://前缀是WeasyPrint识别本地文件的关键。

4. 检查文件权限与字体有效性

  • 确保字体文件的读取权限:在Linux/macOS环境下,执行chmod 644 /path/to/gallery/static/fonts/PlayfairDisplay-Regular.ttf,赋予进程读取权限。
  • 验证字体文件完整性:尝试用系统字体查看器打开字体文件,确认是未损坏的TrueType格式文件;同时检查文件名大小写(Linux系统大小写敏感)是否与模板中完全一致。

5. 调整@font-face的定义细节

  • 补充必要的字体属性,避免解析歧义:
    @font-face {
      font-family: 'Playfair Display';
      font-weight: normal;
      font-style: normal;
      src: url({% static 'fonts/PlayfairDisplay-Regular.ttf' %}) format("truetype");
      font-display: swap;
    }
    

内容的提问来源于stack exchange,提问作者charliesneath

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 06:05:37