Download raw data

csv_string = “data:text/csv;charset=utf-8,” + urllib.parse.quote(csv_string)

instead of
csv_string = “data:text/csv;charset=utf-8,” + urllib.quote(csv_string)

worked for me

The example you posted doesn’t work. I get the same syntax as @pray

Here is a cleaned up working example

import dash
import dash_core_components as dcc
import dash_html_components as html
import pandas as pd
import urllib
#from urllib.parse import urlparse
#import urllib.parse
#urllib.parse.quote
#from urllib.quote import quote

df = pd.DataFrame({
    'a': [1, 2, 3, 4],
    'b': [2, 1, 5, 6],
    'c': ['x', 'x', 'y', 'y']
})


def generate_table(dataframe, max_rows=10):
    return html.Table(
        # Header
        [html.Tr([html.Th(col) for col in dataframe.columns])] +

        # Body
        [html.Tr([
            html.Td(dataframe.iloc[i][col]) for col in dataframe.columns
        ]) for i in range(min(len(dataframe), max_rows))]
    )


app = dash.Dash(__name__)
app.css.append_css({"external_url": "https://codepen.io/chriddyp/pen/bWLwgP.css"})
app.layout = html.Div([
    html.Label('Filter'),

    dcc.Dropdown(
        id='field-dropdown',
        options=[
            {'label': i, 'value': i} for i in
            (['all'] + list(df['c'].unique()))],
        value='all'
    ),
    html.Div(id='table'),
    html.A(
        'Download Data',
        id='download-link',
        download="rawdata.csv",
        href="",
        target="_blank"
    )
])


def filter_data(value):
    if value == 'all':
        return df
    else:
        return df[df['c'] == value]


@app.callback(
    dash.dependencies.Output('table', 'children'),
    [dash.dependencies.Input('field-dropdown', 'value')])
def update_table(filter_value):
    dff = filter_data(filter_value)
    return generate_table(dff)


@app.callback(
    dash.dependencies.Output('download-link', 'href'),
    [dash.dependencies.Input('field-dropdown', 'value')])
def update_download_link(filter_value):
    dff = filter_data(filter_value)
    csv_string = dff.to_csv(index=False, encoding='utf-8')
    csv_string = "data:text/csv;charset=utf-8,%EF%BB%BF" + urllib.parse.quote(csv_string)
    return csv_string


if __name__ == '__main__':
    app.run_server(debug=True)```
1 Like

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

@app.callback(Output('download-link-2', 'href'),
               [Input(component_id='download-link-2',component_property='n_clicks')],
               [State(component_id='data-stored-2',component_property='data')])
def download_data_2(clicks,data):
    data = pd.DataFrame(data,columns=df.columns)
    csv_string = data.to_csv(index=False, encoding='utf-8')
    csv_string = "data:text/csv;charset=utf-8,%EF%BB%BF" + parse.quote(csv_string)
    return csv_string
                
host = socket.gethostbyname(socket.gethostname())
app.run_server(debug=False, host=host, port = 1001)
1 Like

Has anyone found a solution to dayxx369’s problem? I have encountered the same issue.

1 Like

The solution I described here should work:

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.

Hi Chris, is it also possible to give a path/location where the data should be exported to?

3 Likes

@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’,’?’)

Is adding a file path browser possible when you click a download button?

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):

dcc.Tab(label=‘Weather’, children=[
html.Div([
html.H4(string_weather),
html.Iframe(id=‘map1’, srcDoc = open(’/home/tanthiamhuat/DataAnalyticsPortal/data/SingaporeWeather.html’,‘r’).read(), width=‘100%’,height=‘530’),
html.A(
‘Download Data’,
id=‘download-link’,
download=“Weather.csv”,
href="",
target="_blank"
)
]),
]),

@app.callback(
Output(‘download-link’, ‘href’),
[Input(‘cust-dropdown’, ‘value’)]
)
def update_download_link():
Temperature_Rainfall = pd.read_csv(’/home/tanthiamhuat/DataAnalyticsPortal/data/Location_DeviceTemperatureRainfall.csv’)
csv_string = Temperature_Rainfall.to_csv(index=False, encoding=‘utf-8’)
csv_string = “data:text/csv;charset=utf-8,%EF%BB%BF” + urllib.parse.quote(csv_string)
return csv_string

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?

Thanks very helpful!

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?

Hey - I’m getting a syntax error in this part. Can you please advise?

f’/export/excel?option={filter_value}’

Hey!
@chriddyp

I tried using this code and run it without any changes. The file downloaded is not in the correct format. Can you help me resolve this

HI,

I have the same problem… did you solve it?

Best,

I wrote a download component some time ago. Here is a small example,

2 Likes

This is great, thank you so much! I’d managed to get the CSV download working in Chrome but IE was not having it. This appears to solve my issue.

Did you ever solve this?

1 Like

Used urlllib.parser.qoute(); however, I also have the same problem!

1 Like

Did you try the Download component?

1 Like