在web后端开发中,经常有遇到返回一个Excel文件给前端的情况,这里以Python 的Flask web框架为例,其他框架类似,总结一下Flask中返回一个xlsx的文件给前端的情况。
1、以静态文件的形式返回
@app.route('/download_file/<path:filepath>/', methods=["GET"])
def download_file(filepath):
return app.send_static_file(filepath)
2、 以动态文件形式返回
@app.route('/download__xls', methods=["GET"])
def download_xls():
return send_from_directory(directory='./', filename='1.xlsx', as_attachment=True)
3、以内存文件,二进制流文件形式返回
@app.route('/download__xls', methods=["GET"])
def download_xls():
bio = os.BytesIO()
writer = pd.ExcelWriter(bio, engine='xlsxwriter')
# 省略pandas处理结果,results为最后生成的dataframe对象
results.to_excel(writer, sheet_name='结果汇总')
writer.save()
bio.seek(0) # 文件指针
rv = make_response(bio.getvalue())
bio.close()
# mime_type = mimetypes.guess_type(results)[0] # 文件类型
rv.headers['Content-Type'] = "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
rv.headers["Cache-Control"] = "no-cache"
rv.headers['Content-Disposition'] = 'attachment; filename={}.xlsx'.format('Output')
return rv
4、内存文件二进制流的形式 的另外方式
@server.route("/exportSignData", methods=["GET"])
def exportSignData():
# 创建excel表格
excelName = '测试.xlsx'
resIoBytes = BytesIO()
wb = Workbook(resIoBytes)
sheet = wb.add_worksheet()
sheet.write("A1","测试数据")
# 返回文件流
wb.close()
resIoBytes.seek(0)
return send_file(resIoBytes, as_attachment=True, attachment_filename=f"{excelName}")
本文参考了flask 如何处理和下载中文文件名的文件office excel word 和Flask中返回Excel的若干种方案的代码,从实际测试效果来看,第4种形式可以快速解决问题,第三种方式中若文件名有中文,则会报错:'latin-1' codec can't encode characters
解决方案参考:https://blog.csdn.net/qq_41703291/article/details/87886397,这片文章末尾给出了较好的解决方案。第4种方式没有出现此问题。