如何在Python中通过HTTP请求显示或保存Flask服务端返回的xlsx文件?
Flask回传xlsx文件的客户端接收与验证方案
业务流程背景
当前业务链路为:客户端向Flask服务端提交业务参数,服务端基于参数用xlsxwriter生成xlsx文件并存储在本地,通过send_file接口回传文件给客户端,最终在客户端侧完成文件展示或存储。
目前服务端生成文件逻辑运行正常,接口返回状态码200无报错,但客户端直接打印响应内容时会显示大量不可读字符、转义类反斜杠内容,无法确认文件回传是否正确,也缺少客户端处理返回文件的标准实现。
服务端当前回传代码示例:
# 相对路径回传 return send_file("my_file.xlsx", as_attachment=True) # 绝对路径回传 return send_file("absolute/path/to/my_file", as_attachment=True)
客户端当前测试代码示例:
# 发起请求 r = requests.get('http://127.0.0.1:5000/', params={...}) # 直接打印响应内容,输出为不可读二进制字符 print(r.content)
核心问题解决方法
服务端回传正确性的验证方式
- 首先明确认知:xlsx本质是带固定结构的ZIP压缩包,属于二进制格式文件,直接打印
r.content出现不可读字符、转义内容是正常现象,不是回传错误。 - 可通过三个可落地方案快速验证回传正确性:
- 校验响应头信息:检查
r.headers中的Content-Type字段,正常回传xlsx时该值应为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;开启as_attachment=True时,响应头还会携带Content-Disposition字段标注下载文件名。 - 对比文件大小:将服务端本地存储的xlsx文件大小,和
len(r.content)的字节长度做比对,数值完全一致即可确认传输过程无丢包、无内容篡改。 - 内存直接解析验证:通过
io.BytesIO将响应的二进制内容封装为内存文件对象,用openpyxl、pandas等工具直接解析内容,能正常读取到表格数据即说明回传的文件完全可用。
- 校验响应头信息:检查
客户端侧接收、展示或保存xlsx文件的实现
- 核心逻辑:
requests返回对象的r.content属性,就是接口传输的完整二进制文件内容,不需要做任何解码、转义处理,只需以二进制写入模式将内容写入本地xlsx文件,即可得到可正常打开的有效文件。 - 踩坑提醒:绝对不能用
r.text属性处理文件内容,r.text是将响应内容按文本编码规则解码后的字符串,写入文件会直接损坏xlsx格式。 - 无需落盘的内存展示方案:如果不需要先保存本地文件,可以将
r.content封装为BytesIO对象后直接传给pandas读取为DataFrame,在控制台直接打印表格内容,完成快速展示。 - 已验证可用的本地保存实现:
import requests # 按原有业务逻辑发起请求 r = requests.get('http://127.0.0.1:5000/', params={...}) def save_xl(resp): # 必须使用wb(二进制写入)模式打开文件,禁止使用文本写入模式 with open('downloaded_business_file.xlsx', 'wb') as f: f.write(resp.content) save_xl(r)
服务端优化建议
为避免不同部署环境下MIME类型识别不准导致客户端解析异常,使用send_file回传时可以显式声明文件类型、下载文件名:
return send_file( "my_file.xlsx", as_attachment=True, mimetype="application/vnd.openxmlformats-officedocument.spreadsheetml.sheet", download_name="业务导出结果.xlsx" )
内容的提问来源于stack exchange,提问作者jfordummies
相关产品推荐
相关产品推荐

