Facilitated by the need to enable download of in-memory data, i wrote a Download
component some time ago. I have recently updated the code and added a few examples to the documentation. As there has been a number of question on the forum related to downloading data, files, and pandas data frame, i figured it might be of interest to others.
As of version 0.0.18, the basic syntax is like this,
import dash
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download", id="btn"), Download(id="download")])
@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def func(n_clicks):
return dict(content="Hello world!", filename="hello.txt")
if __name__ == '__main__':
app.run_server()
That is, you just add the component anywhere in the layout (like a Store
) and a callback which targets its data
property. The data must be in the form of a dictionary with keys content
(a string) and filename
. To ease the download of files, i have included a file utility function,
import dash
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_file
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download", id="btn"), Download(id="download")])
@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def func(n_clicks):
return send_file("/home/emher/Documents/Untitled.png")
if __name__ == '__main__':
app.run_server()
It takes the file path and optionally a filename (if you want to rename the file on download). Finally, i have included a utility method for data frames,
import dash
import pandas as pd
import dash_html_components as html
from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_data_frame
# Example data.
df = pd.DataFrame({'a': [1, 2, 3, 4], 'b': [2, 1, 5, 6], 'c': ['x', 'x', 'y', 'y']})
# Create app.
app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download", id="btn"), Download(id="download")])
@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def func(n_nlicks):
return send_data_frame(df.to_excel, "mydf.xls", index=False)
if __name__ == '__main__':
app.run_server()
I haven’t tested it extensively, but it should support all pandas file formats except SQL, i.e. json, html, hdf, feather, parquet, megpack, stata and pickle.
I am currently considering moving the Download
component to a separate package, but for the time being, it is part of dash_extensions
. If you would like to try it out, it can be installed via pip,
pip install dash-extensions==0.0.18
Happy downloading