Python-Django中如何生成xlsx文件并实现自动下载功能
Django实现xlsx文件点击下载的解决方案
核心问题说明
你现有代码的逻辑错误是:将生成的xlsx文件存储在了服务端运行进程所属用户的本地Downloads目录,完全没有将文件内容返回给用户的浏览器,因此无法触发前端下载行为。
第一步:修改views.py视图代码
不要将xlsx写入服务端本地磁盘,直接写入内存流后通过响应返回给前端,修改后的代码如下:
import io import xlsxwriter from django.http import HttpResponse from django.views.decorators.csrf import csrf_exempt @csrf_exempt def TestDl(request): if request.method == 'POST': try: # 创建内存流存储xlsx文件,不用写入服务端磁盘 output = io.BytesIO() # 直接将工作簿创建到内存流中 workbook = xlsxwriter.Workbook(output) worksheet = workbook.add_worksheet() # 以下是你原来的表格内容生成逻辑,保持不变 worksheet.set_column('A:A', 50) bold = workbook.add_format({'bold': True}) worksheet.write('A1', 'Hello') worksheet.write('A2', 'World', bold) worksheet.write(2, 3, 312) worksheet.write(2, 8, 'asd') worksheet.write(3, 5, 'hfgh') worksheet.write(5, 2, '312') workbook.close() # 把文件指针移到流的开头 output.seek(0) # 构造文件下载响应 response = HttpResponse( output, # xlsx对应的MIME类型 content_type='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) # 指定文件名,触发浏览器下载行为 response['Content-Disposition'] = 'attachment; filename="demo.xlsx"' return response except Exception as e: # 可打印异常信息排查问题,这里保持原有错误返回逻辑 return HttpResponse('生成文件失败', status=500) return HttpResponse('请求方法错误', status=400)
第二步:前端按钮触发下载的实现
有两种常用实现方式,按需选择即可:
方式1:普通表单提交(最简实现)
页面中写表单和按钮,点击后直接提交即可触发下载,无需写JS:
<form action="/你的TestDl视图对应的url地址/" method="post"> <!-- 如果你后续去掉了csrf_exempt,需要加下面这行csrf token --> <!-- {% csrf_token %} --> <button type="submit">导出Excel</button> </form>
方式2:AJAX请求触发(适合需要传自定义参数的场景)
如果需要异步请求、动态传参,可以用JS处理blob响应触发下载:
<button id="downloadBtn">导出Excel</button> <script> document.getElementById('downloadBtn').addEventListener('click', function() { fetch('/你的TestDl视图对应的url地址/', { method: 'POST', // 如果需要传参数可以加body,需要带csrf token的话也在headers里加 headers: { 'X-CSRFToken': '你的csrf token值' } }).then(res => res.blob()) .then(blob => { // 创建临时下载链接 const url = window.URL.createObjectURL(blob); const a = document.createElement('a'); a.href = url; a.download = 'demo.xlsx'; document.body.appendChild(a); a.click(); // 清理临时资源 window.URL.revokeObjectURL(url); document.body.removeChild(a); }) }) </script>
内容的提问来源于stack exchange,提问作者Asta
相关产品推荐
相关产品推荐

