You need to enable JavaScript to run this app. Django使用Weasyprint生成PDF返回FileResponse显示数字序列如何解决
优惠活动
大模型
产品
解决方案
定价
更多

Django使用Weasyprint生成PDF返回FileResponse显示数字序列如何解决

问题原因
  • Weasyprint的write_pdf()方法返回的是二进制字节流(bytes),而Django的FileResponse要求传入的参数是类文件对象(支持read()方法的对象),而非直接的bytes数据
  • 当你直接把bytes传给FileResponse时,Django会将bytes按单字节迭代,每个字节会被转为对应的十进制数字输出到页面,就是你看到的长串数字。你另一个直接下载原始文件的视图正常,就是因为文件对象本身就是符合要求的类文件对象。
修复方案

方案1(推荐):用BytesIO包装字节流适配FileResponse

把生成的PDF字节流包装为io.BytesIO类文件对象再传给FileResponse即可,修改后的代码如下:

import io
from django.http import FileResponse
from django.shortcuts import get_object_or_404
from weasyprint import HTML, CSS

def download_pdf(request, song_id):
    song = get_object_or_404(Song, pk=song_id)
    song.chordsheet.open("r")
    chordsheet_html = HTML(string=chopro2html(song.chordsheet.read()))
    chordsheet_css = CSS(string="div.chords-lyrics-line {display: flex; font-family: Roboto Mono, monospace;}")
    song.chordsheet.close()
    # 核心修改:把pdf字节流包装为BytesIO类文件对象
    pdf_file = io.BytesIO(chordsheet_html.write_pdf(stylesheets=[chordsheet_css]))
    return FileResponse(pdf_file, as_attachment=True, filename=f"{song.title}_{song.artist}.pdf")

方案2:改用HttpResponse直接返回字节流

不需要额外包装字节流,直接设置响应头即可:

from django.http import HttpResponse
from django.shortcuts import get_object_or_404
from weasyprint import HTML, CSS

def download_pdf(request, song_id):
    song = get_object_or_404(Song, pk=song_id)
    song.chordsheet.open("r")
    chordsheet_html = HTML(string=chopro2html(song.chordsheet.read()))
    chordsheet_css = CSS(string="div.chords-lyrics-line {display: flex; font-family: Roboto Mono, monospace;}")
    song.chordsheet.close()
    pdf_content = chordsheet_html.write_pdf(stylesheets=[chordsheet_css])
    response = HttpResponse(pdf_content, content_type="application/pdf")
    response["Content-Disposition"] = f"attachment; filename={song.title}_{song.artist}.pdf"
    return response

如果文件名包含中文,可以使用Django的urlquote工具处理文件名避免乱码。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.12 09:15:04