2016-02-29 95 views
3

我使用Python 3.5和烧瓶0.10.1并喜欢它,但与send_file有点麻烦。我最终想要处理一个熊猫数据框(来自表单数据,在此示例中未使用,但将来必要时),并将其作为csv(无临时文件)下载。达到这个目标的最好方法就是给我们StringIO。Python烧瓶send_file 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') 

的文件下载适当的名称,但该文件是完全空白。

任何想法?编码问题?这在其他地方有答案吗? 谢谢!

+0

@bernie但是你不能在一个封闭的文件上操作。 –

回答

7

我想你应该写字节。

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) 
+0

是的,它的工作原理 - 我刚刚了解到python 3上的烧瓶不适用于StringIO。后续问题 - 你知道一种将熊猫数据框转换为字节CSV文件进行下载的方法吗? –

+1

@DanielHitchcock嗨,你应该提供一个最小化,完整和可验证的例子,这样我可以重现这个问题(就像这个问题,但与熊猫数据框的例子),我不安静熟悉熊猫,所以我目前的答案是否定的。如有必要,你可以提出另一个问题。 –

1

如果有人在Flask中使用python 2.7,并通过导入模块获得有关模块StringIO的错误。这篇文章可以帮助你解决你的问题。

如果要导入字符串IO模块,你可以使用这个更改导入语法:从IO导入StringIO的代替从StringIO的进口StringIO的

如果您使用的是图像或其他资源,您也可以使用io import BytesIO中的

谢谢

2

这里的问题是,在Python 3,您需要使用StringIOcsv.writesend_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('utf-8')) 
    # seeking was necessary. Python 3.5.2, Flask 0.12.2 
    mem.seek(0) 
    proxy.close(0) 

    return send_file(
     mem, 
     as_attachment=True, 
     attachment_filename='test.csv', 
     mimetype='text/csv' 
    )