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
相关产品推荐
相关产品推荐

