Django生成PDF时错误查找字体路径?出现TTFError报错
解决Django+xhtml2pdf渲染PDF时西里尔字体加载路径错误问题
问题根源
你的代码存在以下几个关键问题:
fetch_resources函数中媒体资源路径处理错误(误用STATIC_ROOT代替MEDIA_ROOT)- 硬编码静态资源URL导致路径解析异常
- 静态文件未正确收集到
STATIC_ROOT目录 - HTML未指定UTF-8编码传递给PDF生成器
分步解决方案
1. 修正资源路径处理函数
更新fetch_resources函数,修复路径逻辑并增加文件存在验证:
import os from django.conf import settings def fetch_resources(uri, rel): # 处理静态文件 if settings.STATIC_URL and uri.startswith(settings.STATIC_URL): path = os.path.join(settings.STATIC_ROOT, uri.replace(settings.STATIC_URL, "")) # 处理媒体文件(修正为MEDIA_ROOT) elif settings.MEDIA_URL and uri.startswith(settings.MEDIA_URL): path = os.path.join(settings.MEDIA_ROOT, uri.replace(settings.MEDIA_URL, "")) else: return uri # 转换为绝对路径并验证文件存在 path = os.path.abspath(path) return path if os.path.exists(path) else uri
2. 修正PDF渲染函数的编码处理
确保HTML以UTF-8编码传递,避免西里尔字符乱码或解析错误:
from django.template.loader import get_template from django.http import HttpResponse from io import BytesIO import xhtml2pdf.pisa as pisa def render_pdf(url_template, context={}): template = get_template(url_template) html = template.render(context) result = BytesIO() # 指定UTF-8编码处理西里尔字符 pdf = pisa.CreatePDF(BytesIO(html.encode("UTF-8")), result, link_callback=fetch_resources) if not pdf.err: return HttpResponse(result.getvalue(), content_type="application/pdf") return None
3. 调整模板中的字体引用
使用Django静态文件标签替代硬编码URL,确保路径正确生成:
{% load static %} {% block extra_style %} <style type="text/css"> @font-face { font-family: Calibri; src: url("{% static 'fonts/Calibri.ttf' %}"); font-display: swap; } body { font-family: 'Calibri', sans-serif; } </style> {% endblock %} {% block content %} <body> <p>йоу</p> </body> {% endblock %}
4. 收集静态文件到STATIC_ROOT目录
运行以下命令,将STATICFILES_DIRS中的资源复制到STATIC_ROOT:
python manage.py collectstatic
执行后确认D:\你的项目路径\static\fonts\Calibri.ttf文件存在。
5. 完善视图错误处理
避免返回空值导致的异常:
from django.views.generic import View class DownloadPDF(View): def get(self, request, *args, **kwargs): pdf = render_pdf("tmp.html") if pdf: return pdf return HttpResponse("PDF生成失败", status=500)
额外检查项
- 确保运行Django服务器的用户对
STATIC_ROOT/fonts目录有读取权限 - 检查系统临时目录(
C:\Users\slavk\AppData\Local\Temp)的读写权限,必要时更换临时目录
内容的提问来源于stack exchange,提问作者SLDem
相关产品推荐
相关产品推荐

