Flask向AngularJS返回XlsxWriter生成的Excel文件损坏,请求排查
解决XlsxWriter生成的Excel文件在Flask+AngularJS下载时损坏的问题
我之前也碰到过一模一样的坑,大概率是响应头设置不全或者AngularJS端对二进制数据处理不当导致的,咱们一步步来修复:
一、Flask视图层的关键修正
你的代码里漏掉了几个核心响应头,而且MIME类型看起来没写完整,这里给你调整后的完整代码:
from flask import Response import io import xlsxwriter def export_excel(): output = io.BytesIO() workbook = xlsxwriter.Workbook(output, {'in_memory': True}) # 这里是你添加数据的业务代码,举个例子: worksheet = workbook.add_worksheet("数据页") worksheet.write('A1', '姓名') worksheet.write('B1', '年龄') worksheet.write('A2', '张三') worksheet.write('B2', 28) # 必须先关闭工作簿,XlsxWriter才会把所有数据写入BytesIO workbook.close() output.seek(0) # 完善响应配置,这是解决文件损坏的核心 response = Response( output.getvalue(), mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) # 告诉浏览器这是附件,指定下载文件名 response.headers["Content-Disposition"] = "attachment; filename=export_data.xlsx" # 可选但推荐:设置文件大小,避免部分浏览器解析时截断数据 response.headers["Content-Length"] = str(len(output.getvalue())) return response
需要注意这几个细节:
- 必须使用完整的XLSX标准MIME类型:
application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,不能简写 Content-Disposition头是刚需,没有它浏览器可能会把二进制数据当成文本解析,直接破坏文件结构- 一定要先执行
workbook.close()再调用output.seek(0),XlsxWriter只有关闭工作簿时才会完成所有数据的写入
二、AngularJS端的二进制数据处理
如果Flask端改完还是报错,那问题肯定出在前端——默认的$http请求会把响应当成文本处理,直接破坏二进制数据,你需要这样调整:
$http.get('/your-flask-export-endpoint', {responseType: 'arraybuffer'}) .then(function(response) { // 创建Blob对象存储二进制数据 var blob = new Blob([response.data], { type: 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' }); // 生成临时下载链接 var downloadUrl = window.URL.createObjectURL(blob); var aTag = document.createElement('a'); aTag.href = downloadUrl; aTag.download = 'export_data.xlsx'; // 和后端文件名保持一致 document.body.appendChild(aTag); aTag.click(); // 清理临时资源 window.URL.revokeObjectURL(downloadUrl); document.body.removeChild(aTag); });
这里的核心是设置responseType: 'arraybuffer',让AngularJS知道要处理的是二进制数据,而不是默认的JSON或文本。
三、额外排查小技巧
如果还是不行,先把生成的Excel保存到本地测试:
# 在workbook.close()之后添加这段代码,检查文件本身是否正常 with open('test_local.xlsx', 'wb') as f: f.write(output.getvalue())
如果本地打开正常,那问题肯定在前后端的传输/处理环节;如果本地打开也损坏,那就是你添加数据的业务代码有问题,比如写入了XlsxWriter不支持的格式。
内容的提问来源于stack exchange,提问作者mia
相关产品推荐
相关产品推荐

