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

Django中如何将DO Spaces存储的图片插入ReportLab生成的PDF

问题:ReportLab无法加载DigitalOcean Spaces中的SVG图片

问题场景

我尝试将存在DigitalOcean Spaces里的SVG logo插入到ReportLab生成的PDF中,写的代码是:

pdf.drawImage('https://dummy-bucket.sgp1.digitaloceanspaces.com/static/images/logo_name_header.svg', -0.10*cm,10*cm)

但运行时直接报错:

fileName=<__io.BytesIO object at 0x000001D1CE603A90> identity=[ImageReader@0x1d1ce5e6f70] cannot identify image file <_io.BytesIO object at 0x000001D1CE603A90>

图片用浏览器能正常打开,完整代码如下:

def get_pdf(request):
    
    data= {
       ... some data 
        
        }    
        
    
    try:
    
        buffer = io.BytesIO()

       
        pdf = canvas.Canvas(buffer, pagesize=A4)
        
        
        pdf = base_temp(pdf, data)  #base temp is a pre designed canvas
        pdf.setTitle("Invoice")
        
        
 
        pdf.drawImage('https://dummy-bucket.sgp1.digitaloceanspaces.com/static/images/logo_name_header.svg', -0.10*cm,10*cm)

        
        pdf.showPage()
        
        pdf.save()    
        
        buffer.seek(0)

        # sending pdf as a response
        response =  FileResponse(buffer)
        
        # setting the content-type to pdf
        response['Content-Type'] = 'application/pdf'  
        
        # telling the response that it is a pdf file
        response['Content-Disposition'] = f'inline; filename="{data["invoice_number"]}.pdf"'
        
        return response
    except Exception as e:
        
        print(e)
        
        return HttpResponse(str(e))

原因

ReportLab的drawImage本身不支持SVG格式,它只认PNG、JPG这类光栅图。另外就算是支持的格式,直接传远程URL也可能因为底层读取逻辑的问题加载失败,更别说不兼容的SVG了。

解决方案

有两种靠谱的解决办法:

办法1:把SVG转成PNG/JPG再加载

先把SVG下载到内存里,转成ReportLab支持的格式,再插入PDF。用cairosvg就能完成转换:

  1. 先装依赖:
pip install cairosvg requests
  1. 修改代码:
import requests
import cairosvg
from io import BytesIO

def get_pdf(request):
    data = {
        # ... 你的业务数据
    }    
    try:
        buffer = io.BytesIO()
        pdf = canvas.Canvas(buffer, pagesize=A4)
        pdf = base_temp(pdf, data)
        pdf.setTitle("Invoice")
        
        # 1. 下载SVG内容
        svg_url = 'https://dummy-bucket.sgp1.digitaloceanspaces.com/static/images/logo_name_header.svg'
        svg_resp = requests.get(svg_url)
        svg_resp.raise_for_status()  # 确保请求没出错
        
        # 2. 把SVG转成PNG存在内存里
        png_buffer = BytesIO()
        cairosvg.svg2png(bytestring=svg_resp.content, write_to=png_buffer)
        png_buffer.seek(0)  # 把指针移到文件开头
        
        # 3. 插入转好的PNG到PDF
        pdf.drawImage(png_buffer, -0.10*cm, 10*cm)
        
        pdf.showPage()
        pdf.save()    
        buffer.seek(0)

        response = FileResponse(buffer)
        response['Content-Type'] = 'application/pdf'  
        response['Content-Disposition'] = f'inline; filename="{data["invoice_number"]}.pdf"'
        return response
    except Exception as e:
        print(e)
        return HttpResponse(str(e))

办法2:用ReportLab的SVG扩展

ReportLab有个rl_svg扩展可以直接处理SVG,步骤更简单:

  1. 装依赖:
pip install reportlab-svg
  1. 修改代码:
from rl_svg import draw_svg

def get_pdf(request):
    data = {
        # ... 你的业务数据
    }    
    try:
        buffer = io.BytesIO()
        pdf = canvas.Canvas(buffer, pagesize=A4)
        pdf = base_temp(pdf, data)
        pdf.setTitle("Invoice")
        
        # 用rl_svg直接加载并绘制SVG
        svg_url = 'https://dummy-bucket.sgp1.digitaloceanspaces.com/static/images/logo_name_header.svg'
        draw_svg(pdf, svg_url, x=-0.10*cm, y=10*cm)
        
        pdf.showPage()
        pdf.save()    
        buffer.seek(0)

        response = FileResponse(buffer)
        response['Content-Type'] = 'application/pdf'  
        response['Content-Disposition'] = f'inline; filename="{data["invoice_number"]}.pdf"'
        return response
    except Exception as e:
        print(e)
        return HttpResponse(str(e))

额外提醒

  • 如果用cairosvg,服务器环境需要装系统依赖libcairo2,Ubuntu下可以用apt install libcairo2安装
  • 如果你的DigitalOcean Spaces需要权限访问,要在请求里加对应的认证信息(Spaces兼容S3 API,用AWS签名逻辑就行)
  • 可以加个缓存,别每次生成PDF都重新下载转换SVG,能提升性能

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 01:16:09