Home > OS >  Python, Dash - Download Generated Excel File on Click
Python, Dash - Download Generated Excel File on Click

Time:02-06

I'm trying to make a Dash App that lets the user download an Excel that is generated through the following function:

def Create_Excel(perfume_name):

   workbook = xlsxwriter.Workbook(r'D:\Perfumes\\'   perfume_name   ".xlsx")
   worksheet = workbook.add_worksheet()

   worksheet.write('A1', 'Perfume')
   worksheet.write('B1', 'Preços(€)')
   worksheet.write('C1', 'Link')
   worksheet.write('D1', 'Disponibilidade (caso possível)')
   worksheet.write('E1', 'OLX Local')
   worksheet.write('F1', 'ML')

   workbook.close()

def main():
   perfume = input()
   Create_Excel(perfume)

I have the following code that works for a static filepath:

import dash
import pandas as pd
from dash import html as html
from dash.dependencies import Output, Input
from dash_extensions import Download
from dash_extensions.snippets import send_bytes
from Excel import *

app = dash.Dash(prevent_initial_callbacks=True)
app.layout = html.Div([html.Button("Download xlsx", id="btn"), Download(id="download")])



Create_Excel('Teste')
df = pd.read_excel(r'D:\Perfumes\Teste.xlsx')


@app.callback(Output("download", "data"), [Input("btn", "n_clicks")])
def generate_xlsx(excel):

    def to_xlsx(bytes_io):
        xslx_writer = pd.ExcelWriter(bytes_io, engine="xlsxwriter")
        df.to_excel(xslx_writer, index=False, sheet_name="sheet1")
        xslx_writer.save()

    return send_bytes(to_xlsx, "Download_Perfume.xlsx")


if __name__ == '__main__':
    app.run_server()

This works, but I want to share the app with other people.

The objective is for the user to click the button and be asked for the perfume input, then generate the excel file and download it. So the filepath would be variable and the perfume input would also change.

Thank you!

CodePudding user response:

You could have 2 inputs for taking in the values you want dynamically, and a submit button to process those inputs for your generation function, so something like this as a template:

app.layout = html.Div(children=[
    dcc.Input(id="input_1"),
    dcc.Input(id="input_2"),
    html.Button('Submit', id='submit-val'),
    dbc.Label(id="result")
])

@app.callback(
    Output("result", "children"),
    [
        Input("submit-val", "n_clicks"),
    ],
    [
        State("input_1", "value"),
        State("input_2", "value")
    ], prevent_initial_call=True
)
def get_inputs(_, input_1, input_2):
    return f"{input_1}, {input_2}"
  •  Tags:  
  • Related