Python Flask send_file StringIO 空白文件

Python Flask send_file StringIO blank files

我正在使用 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')

下载了一个具有正确名称的文件,但是该文件是完全空白的。

有什么想法吗?编码问题?这在别处得到回答了吗? 谢谢!

我想你应该写字节。

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 2.7 与 Flask 一起使用,并通过导入它得到了关于模块 StringIO 的错误。这个post可以帮你解决问题。

如果您正在导入 String IO 模块,您可以使用以下方法更改导入语法:from io import StringIO 而不是 from StringIO import StringIO

如果您使用图像或其他一些资源,您也可以使用 from io import BytesIO

谢谢

这里的问题是,在 Python 3 中,您需要将 StringIOcsv.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'
    )

make_response

  • 为了让 Flask 下载 csv 文件给用户,我们将 csv 字符串传递给 make_response 函数,其中returns一个 Response 对象。
  • 然后我们添加一个 Header 告诉浏览器接受文件作为下载。
  • Mimetype 也必须设置为 text/csv 才能使网络浏览器将其保存为 [=55 以外的格式=] 文件.
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. It is preferred to use python's built-in csv library to deal with csv files

参考资料

合十礼