I have an Excel file dynamically generated based on a variable called “option”, so in my layout I have a button like this (in this example option=foo but these links are dynamically generated):
html.A(html.Button('Export to Excel'), href=f'/export/excel?option=foo')
And I create a flask route like this:
@app.server.route('/export/excel')
def export_excel_file():
option = flask.request.args.get('option')
if any(l not in string.ascii_letters for l in option):
raise ValueError('Option contains unexpected characters')
option_df = function_that_generates_dataframe(option)
xlsx_io = io.BytesIO()
writer = pd.ExcelWriter(xlsx_io, engine='xlsxwriter')
option_df.to_excel(writer, sheet_name=option)
writer.save()
xlsx_io.seek(0)
return flask.send_file(
xlsx_io,
mimetype='application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
attachment_filename=f'export_{option}.xlsx',
as_attachment=True,
cache_timeout=0
)
This works perfectly for me, you may be able to simplify it if you don’t need to pass in a variable.
Is it also possible to pass on data that I have just created in the application? So that I no longer use a global pandas DataFrame but pass on data with json or bytes format to the download component?
Something I have noticed is that when I use the csv download method, I keep getting the previous dataframe that was created when I pass in the dataframe in the method instead of having a method (filter_data) create the dataframe locally. Is there a way to get the current dataframe that’s being used in the program? I store my data in Store, which is not typically a problem to get because I don’t get this issue with other parts of my program
It saves data based on what is contained within the dcc.Graph.figure.data object, but can easily be modified to handle the contents of dcc.Store.data or dt.DataTable.data.
edit doing so for a server-side thing won’t be possible. I suppose using the simple example from dayxx369, you would pass in State('table', 'children') and need to parse that to regenerate the CSV.
@chriddyp how can we choose what the filename is? instead of download=‘rawdata’ can we set this via an input box? I just don’t know what to return in Output(‘id’,’?’)
Hi Chris,
I have the same problem as what Pray is facing. Going through all those postings, it still does not help.
My code as below (I am using Python 3):
Take note here, I have no Input for that Download link, and I am using some other which is not related to that Download link. If that Download link is not related to any input, how should we put it?
I’ve a slightly different use case: Instead of providing a download link for a csv file I provide a download link for a plain text file with link = "data:text/plain;charset=utf-8," + urllib.parse.quote(text). However the text is formatted and I’m getting the text in the file unformatted. I’ve not found another suitable media type which could work for me. Has someone an idea how to fix this?