Django REST Framework中WeasyPrint生成PDF如何插入图片/Logo?
在Django+WeasyPrint生成的PDF中添加图片/Logo
当然可以给PDF添加图片或Logo,下面是两种实用的实现方式:
方法一:传递本地图片绝对路径到模板
先把你的Logo图片放到静态文件目录下,比如对应你代码里的
app_static_dir,路径设为pdf/static/images/logo.png。修改视图函数,把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
- 在
sell_invoice.html模板中引用该路径:
<img src="{{ logo_path }}" alt="公司Logo" style="width: 120px; height: auto;">
方法二:使用Django静态文件标签(推荐)
这种方式更符合Django的静态文件管理规范:
同样把Logo放在
pdf/static/images/logo.png目录下。在模板
sell_invoice.html中使用static标签引用图片:
{% load static %} <div class="invoice-header"> <img src="{% static 'images/logo.png' %}" alt="公司Logo" style="width: 120px; height: auto;"> <!-- 其他发票内容 --> </div>
- 修改视图函数,给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
相关产品推荐
相关产品推荐

