Python Flask send_file StringIO 空白文件
Posted
技术标签:
【中文标题】Python Flask send_file StringIO 空白文件【英文标题】:Python Flask send_file StringIO blank files 【发布时间】:2016-06-13 03:07:29 【问题描述】:我正在使用 python 3.5 和flask 0.10.1 并且喜欢它,但是在使用 send_file 时遇到了一些问题。我最终想要处理一个 pandas 数据帧(来自表单数据,在本示例中未使用,但将来需要)并将其发送为 csv 下载(没有临时文件)。我见过的最好的实现方法是 StringIO。
这是我尝试使用的代码:
@app.route('/test_download', methods = ['POST'])
def test_download():
buffer = StringIO()
buffer.write('Just some letters.')
buffer.seek(0)
return send_file(buffer, as_attachment = True,\
attachment_filename = 'a_file.txt', mimetype = 'text/csv')
使用正确名称下载文件,但该文件完全为空白。
有什么想法吗?编码问题?这在其他地方得到了回答吗? 谢谢!
【问题讨论】:
@bernie 但是你不能对关闭的文件进行操作。 【参考方案1】:这里的问题是,在 Python 3 中,您需要将 StringIO
与 csv.write
一起使用,而 send_file
需要 BytesIO
,因此您必须同时使用两者。
@app.route('/test_download')
def test_download():
row = ['hello', 'world']
proxy = io.StringIO()
writer = csv.writer(proxy)
writer.writerow(row)
# Creating the byteIO object from the StringIO Object
mem = io.BytesIO()
mem.write(proxy.getvalue().encode())
# seeking was necessary. Python 3.5.2, Flask 0.12.2
mem.seek(0)
proxy.close()
return send_file(
mem,
as_attachment=True,
attachment_filename='test.csv',
mimetype='text/csv'
)
【讨论】:
这应该是公认的答案,因为它在使用 send_file() 方法导出/下载 CSV 文件的意义上更通用。 在编码中我添加了"utf-8-sig"
,或者你可能想要"utf-8"
。另见***.com/questions/2223882/…【参考方案2】:
我猜你应该写字节。
from io import BytesIO
from flask import Flask, send_file
app = Flask(__name__)
@app.route('/test_download', methods=['POST'])
def test_download():
# Use BytesIO instead of StringIO here.
buffer = BytesIO()
buffer.write(b'jJust some letters.')
# Or you can encode it to bytes.
# buffer.write('Just some letters.'.encode('utf-8'))
buffer.seek(0)
return send_file(buffer, as_attachment=True,
attachment_filename='a_file.txt',
mimetype='text/csv')
if __name__ == '__main__':
app.run(debug=True)
【讨论】:
是的,这行得通——我刚刚了解到 python 3 上的烧瓶不适用于 StringIO。跟进问题-您知道将熊猫数据帧转换为字节 csv 以供下载的方法吗? @DanielHitchcock 嗨,您应该提供一个最小、完整和可验证的示例,以便我可以重现这个问题(比如这个问题,但是使用 pandas 数据框示例),我对 pandas 并不熟悉所以我目前的答案是否定的。如有必要,您可以提出其他问题。 关键部分是“buffer.seek(0)” - 我遇到了来自 pandas 的 excel 文件的问题,并通过这一行解决了【参考方案3】:make_response
为了让 Flask 将 csv 文件下载给用户,我们将 csv 字符串传递给 make_response
函数,该函数返回一个
Response
对象。
然后我们添加一个 Header 告诉浏览器接受文件作为下载。
Mimetype 也必须设置为 text/csv
,以便让网络浏览器将其保存在 html 文档以外的其他文件中。
from flask import Flask, make_response
app = Flask(__name__)
@app.route('/test_download', methods=['POST'])
def test_download():
with StringIO() as buffer:
# forming a StringIO object
buffer = StringIO()
buffer.write('Just some letters.')
# forming a Response object with Headers to return from flask
response = make_response(buffer.getvalue())
response.headers['Content-Disposition'] = 'attachment; filename=namaste.csv'
response.mimetype = 'text/csv'
# return the Response object
return response
P.S.最好使用python内置的
csv
库处理csv
文件
参考文献
https://matthewmoisen.com/blog/how-to-download-a-csv-file-in-flask/ https://www.geeksforgeeks.org/stringio-module-in-python/ https://docs.python.org/3/library/csv.html合十礼?
【讨论】:
【参考方案4】:如果有人在 Flask 中使用 python 2.7 并通过导入模块 StringIO 得到错误。这篇文章可以帮助你解决你的问题。
如果您正在导入 String IO 模块,您可以使用以下命令更改导入语法:from io import StringIO 而不是 from StringIO import StringIO。
如果您使用图像或其他一些资源,您也可以使用 from io import BytesIO。
谢谢
【讨论】:
以上是关于Python Flask send_file StringIO 空白文件的主要内容,如果未能解决你的问题,请参考以下文章
使用Python Flask中的send_file发送视频时移动设备发生错误http://mattspitz.me/2013/11/20/serving-authenticated-media-wit