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

Django REST Framework中WeasyPrint生成PDF如何插入图片/Logo?

当然可以给PDF添加图片或Logo,下面是两种实用的实现方式:

方法一:传递本地图片绝对路径到模板

  1. 先把你的Logo图片放到静态文件目录下,比如对应你代码里的app_static_dir,路径设为pdf/static/images/logo.png。

  2. 修改视图函数,把Logo的绝对路径传给模板:

import weasyprint
import os
from django.shortcuts import render_to_string
from django.http import HttpResponse
from .models import Sell
from django.conf import settings

def admin_order_pdf(request, sell_id):
    try:
        sell = Sell.objects.get(id=sell_id)
    except Sell.DoesNotExist:
        return HttpResponse('Sell object does not exist')

    app_static_dir = os.path.join(settings.BASE_DIR, 'pdf', 'static')
    # 生成Logo的绝对路径
    logo_path = os.path.join(app_static_dir, 'images', 'logo.png')
    # 把logo_path传入模板
    html = render_to_string('sell_invoice.html', {'sell': sell, 'logo_path': logo_path})
    
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'filename=sell_{sell.id}.pdf'

    css_path = os.path.join(app_static_dir, 'css', 'css.css')

    weasyprint.HTML(string=html).write_pdf(response, stylesheets=[weasyprint.CSS(css_path)])

    return response
  1. 在sell_invoice.html模板中引用该路径:
<img src="{{ logo_path }}" alt="公司Logo" style="width: 120px; height: auto;">

方法二:使用Django静态文件标签(推荐)

这种方式更符合Django的静态文件管理规范:

  1. 同样把Logo放在pdf/static/images/logo.png目录下。

  2. 在模板sell_invoice.html中使用static标签引用图片:

{% load static %}
<div class="invoice-header">
    <img src="{% static 'images/logo.png' %}" alt="公司Logo" style="width: 120px; height: auto;">
    <!-- 其他发票内容 -->
</div>
  1. 修改视图函数,给WeasyPrint的HTML对象设置base_url参数,让它能正确解析静态文件的URL:
def admin_order_pdf(request, sell_id):
    try:
        sell = Sell.objects.get(id=sell_id)
    except Sell.DoesNotExist:
        return HttpResponse('Sell object does not exist')

    html = render_to_string('sell_invoice.html', {'sell': sell})
    
    response = HttpResponse(content_type='application/pdf')
    response['Content-Disposition'] = f'filename=sell_{sell.id}.pdf'

    app_static_dir = os.path.join(settings.BASE_DIR, 'pdf', 'static')
    css_path = os.path.join(app_static_dir, 'css', 'css.css')

    # 设置base_url,让WeasyPrint能找到静态文件
    # 方式1:使用当前请求的绝对URI作为基础
    weasyprint.HTML(string=html, base_url=request.build_absolute_uri()).write_pdf(
        response, 
        stylesheets=[weasyprint.CSS(css_path)]
    )

    # 方式2:直接用静态目录的文件协议路径(适合本地测试)
    # base_url = f'file://{app_static_dir}/'
    # weasyprint.HTML(string=html, base_url=base_url).write_pdf(...)

    return response

注意事项

  • 确保WeasyPrint有读取图片文件的权限,本地开发一般没问题,生产环境要注意静态文件目录的权限设置。
  • 支持的图片格式包括PNG、JPG、SVG等,SVG可能需要额外配置,优先用PNG/JPG更稳定。
  • 可以通过CSS控制图片的大小、对齐等样式,和普通HTML页面一样。

内容的提问来源于stack exchange,提问作者Nayem Jaman Tusher

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 19:46:17