0

I am reading user inputs and sending them for processing. After processing, the results are displayed. Along with the results I want a link on webpage to be able to download the data as a csv file. My function to process inputs looks as follows.

@app.route('/process', methods=['POST'])
def process_data():
    # create csv_file
    return render_template("results.html", data=csv_file)

results.html has following line.

<p><a href="{{ url_for('download', filename=data) }}"> <large>Download simulation data </large></a></p>

This link is correctly displayed on the webpage. My function to download the data looks as follows.

@app.route('/download/<filename>')
def download(filename):
    response = make_response(filename)
    response.headers["Content-Disposition"] = "attachment; filename=Simulation.csv"
    response.headers["Content-Type"] = "text/csv"
    return response

Clicking the download link, I get '414 Request-URI Too Large'.

Is there a better solution for passing data from flask to html to flask again? I can see that my entire data are appended to url, can I somehow avoid that? Is it possible to directly pass response while rendering results.html and make it downloadable?

UPDATE

I learnt that putting data in url is a bad idea. Instead I can use dataurl by encoding the data and then use dataurl for csv in href tag of html.

buffer = StringIO()
dataframe.to_csv(buffer, index=False)
buffer.seek(0)
data_str = base64.b64encode(buffer.getvalue().encode('utf8')).decode('ascii')
url = "data:text/csv; base64,{}".format(data_str)

html looks like as follows.

<a download="SSW_Simulation.csv" href="{{ data_url }}">download</a>

However this solution does not work in internet explorer I guess because urls for data are not supported. Should I be saving the csv file somewhere and pass that filename to html? so that when prompted, I can fetch it from the temporary location and download using make_response? I would prefer not to save the file to the disk.

Bhushan
  • 21
  • 4
  • 1
    Is `csv_file` a filename or a string containing the data formatted as csv? – Jeronimo Dec 12 '19 at 15:09
  • a string containing the data formatted as csv. – Bhushan Dec 13 '19 at 20:13
  • Maybe this https://stackoverflow.com/questions/24898044/is-possible-to-save-javascript-variable-as-file can help you. They put the data into a javascript variable and make that downloadable as a file. – Jeronimo Dec 16 '19 at 06:40
  • That seems to be the way to go about it. The answer [here](https://stackoverflow.com/a/30832210/9199084) helped. – Bhushan Dec 17 '19 at 16:46

1 Answers1

1

Handling the data in javascript solved the problem as suggested by @Jeronimo. json string was passed to html page.

import json

@app.route('/process', methods=['POST'])
def process_data():
    # create csv_file
    data = json.dumps(csv_file)
    return render_template("results.html", data=data)

Javascript suggested in this answer was added to html and along with download button.

<button onclick="download({{ data }}, 'myfile.csv', 'text/csv')">download data</button>
Bhushan
  • 21
  • 4