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

Django使用pisa渲染HTML生成PDF时图片无法显示问题求助

问题根因

你使用的xhtml2pdf(pisa)渲染PDF时无法识别HTML中的相对静态资源路径,需要传入完整的绝对文件系统路径或者带域名的完整公开URL才能正常加载图片。


可行修改方案

1. 修改视图函数

提前在视图层计算好图片的绝对路径传入模板,避免模板侧拼接相对路径找不到资源:

from django.conf import settings
from django.contrib.staticfiles import finders
import os

def get(request):
    template = get_template('success.html')
    # 计算图片实际本地绝对路径
    img_filename = f"{surname}.png"
    img_relative_path = os.path.join('qrs', img_filename)
    img_absolute_path = finders.find(img_relative_path)
    # 生产环境也可选择拼接完整公网URL:img_full_url = request.build_absolute_uri(f'/static/qrs/{img_filename}')
    context = {
        'img_path': img_absolute_path # 用完整URL的话这里传img_full_url即可
    }
    # 渲染模板时传入request避免上下文缺失
    html = template.render(context, request)
    pdf = render_to_pdf('success.html', context)

    if pdf:
        response = HttpResponse(pdf, content_type='application/pdf')
        # 修复原代码未拼接文件名参数的问题
        filename = f"Paymentslip{surname}.pdf"
        content = f"inline; filename='{filename}'"
        download = request.GET.get("download")
        if download:
            content = f"attachment; filename='{filename}'"
        response['Content-Disposition'] = content
        return response

    return HttpResponse("Not found") 

2. 修改模板文件

直接使用视图传入的绝对路径,不需要在模板侧拼接静态路径:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Success Page</title>
</head>
<body>
    <h1>SUCCESS!!!!</h1>
    <div>
    <img src="{{ img_path }}" alt="qrcode">
    </div>
</body>
</html>

3. 优化utils.py的编码逻辑

修复原代码ISO-8859-1编码可能导致的中文乱码、中文路径识别失败问题:

def render_to_pdf(template_src, context_dict={}):
     template = get_template(template_src)
     html  = template.render(context_dict)
     result = BytesIO()
     # 更换为UTF-8编码,同时显式指定pisa的编码参数
     pdf = pisa.pisaDocument(BytesIO(html.encode("UTF-8")), result, encoding='UTF-8')
     if not pdf.err:
         # 直接返回字节流即可,不需要重复封装HttpResponse
         return result.getvalue()
     return None

注意事项

  • 用本地绝对路径方案的话,部署时需要确保服务运行用户有静态文件目录的读取权限
  • 用完整URL方案的话,需要确保服务器可以正常访问自身的公网域名,没有内网防火墙拦截
  • 如果是加载用户上传的媒体文件,把静态文件查找逻辑替换为os.path.join(settings.MEDIA_ROOT, 媒体文件相对路径)即可

内容的提问来源于stack exchange,提问作者Al-Mahi

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.16 09:54:06