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

Django+HTMX环境下WeasyPrint生成PDF无法下载仅显示乱码

问题根源及解决方案

核心问题出在你的HTMX配置上——页面body的hx-boost='True'会将所有GET请求劫持为AJAX请求。浏览器处理AJAX返回的二进制PDF内容时,不会触发下载逻辑,而是直接把二进制数据当作文本显示,这就是你看到乱码的原因。

快速解决方案(优先推荐)

在触发CreateReportView的链接或按钮上,添加hx-boost="false",跳过HTMX的请求增强,让浏览器正常处理下载响应:

<a href="{% url 'create_report' %}" hx-boost="false">下载PDF报告</a>

修正视图代码(确保PDF生成逻辑正确)

同时,你需要用io.BytesIO包装PDF内容,因为FileResponse需要接收类文件对象,而非直接传入字节字符串。修正后的视图代码如下:

import io  # 必须导入io模块
from django.core.files import File
from django.db.models import Avg, Count, Case, When, IntegerField, DecimalField
from django.http import HttpResponse, FileResponse
from django.shortcuts import render
from django.template.loader import render_to_string
from django.views import View
from weasyprint import HTML
from salary.models import Salary

class CreateReportView(View):
    def get(self, request, *args, ** kwargs):
        # ... 省略无关代码 ...

        context = {'results': results, 'results_per_gender': results_per_gender, 'results_per_region': results_per_region, 'results_titles': results_titles}
        rendered_html = render_to_string('report_template.html', context=context)

        buffer = io.BytesIO()
        HTML(string=rendered_html).write_pdf(buffer)
        buffer.seek(0)  # 将文件指针移到开头,确保能读取完整内容

        # 使用FileResponse返回
        response = FileResponse(buffer, as_attachment=True, filename="test.pdf")
        return response

为什么之前的尝试无效?

  • 你直接将write_pdf()返回的字节字符串传给FileResponse,不符合它的参数要求,虽然本地保存没问题,但返回浏览器时容易和HTMX的AJAX逻辑冲突;
  • 无论是WeasyPrint还是ReportLab都能生成正常PDF,问题不在PDF生成环节,而在请求的处理方式上——HTMX的hx-boost改变了浏览器对响应的处理逻辑。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.24 06:45:13