Create and download a CSV file from a Flask view Create and download a CSV file from a Flask view flask flask

Create and download a CSV file from a Flask view


Generate the data with csv.writer and stream the response. Use StringIO to write to an in-memory buffer rather than generating an intermediate file.

import csvfrom datetime import datetimefrom io import StringIOfrom flask import Flaskfrom werkzeug.wrappers import Responseapp = Flask(__name__)# example data, this could come from wherever you are storing logslog = [    ('login', datetime(2015, 1, 10, 5, 30)),    ('deposit', datetime(2015, 1, 10, 5, 35)),    ('order', datetime(2015, 1, 10, 5, 50)),    ('withdraw', datetime(2015, 1, 10, 6, 10)),    ('logout', datetime(2015, 1, 10, 6, 15))]@app.route('/')def download_log():    def generate():        data = StringIO()        w = csv.writer(data)        # write header        w.writerow(('action', 'timestamp'))        yield data.getvalue()        data.seek(0)        data.truncate(0)        # write each log item        for item in log:            w.writerow((                item[0],                item[1].isoformat()  # format datetime as string            ))            yield data.getvalue()            data.seek(0)            data.truncate(0)    # stream the response as the data is generated    response = Response(generate(), mimetype='text/csv')    # add a filename    response.headers.set("Content-Disposition", "attachment", filename="log.csv")    return response

If the generate function will need information from the current request, it should be decorated with stream_with_context, otherwise you will get a "working outside request context" error. Everything else remains the same.

from flask import stream_with context@stream_with_contextdef generate():    ...


The Flask-Excel library uses PyExcel to generate a CSV or other spreadsheet format and produces a Flask response. The docs list how to produce other formats and the full API for what data can be used.

pip install flask-excel
import flask_excel as excel@app.route('/download', methods=['GET'])def download_data():    sample_data=[0, 1, 2]    excel.init_excel(app)    extension_type = "csv"    filename = "test123" + "." extension_type    d = {'colName': sample_data}    return excel.make_response_from_dict(d, file_type=extension_type, file_name=filename)