How to add a download excel/csv function to a button?

That solved it! Thank you so much!

Why do you need to have the st.download_button function inside with pd.ExcelWriter(…) as writer: ?
Is buffer not stored in memory so you can separate these functions?

1 Like

Yes, it works fine if you put the download button outside of the ExcelWriter context manager

Ok. I’m asking since I manage to do this perfectly locally but when I put it on azure cloud i get “page doesnt exist”. I have set the privileges of the app users and am able to download other pickled files and pdf-files, so I don’t think it’s a security issue. I was thinking there was something going on with what was stored in memory. I also tried to write explicitly to a file, opened the file and used the download_button and then removed the file. That also worked locally but not on cloud. Will now try the link approach (on button click - create a link to download your file), but am just blindly trying out stuff since I don’t understand what’s going on. Any ideas?

 isim= 'Analsed_Data.csv'
 indir = df_analiz_download.to_csv(index=False)
 b64 = base64.b64encode(indir.encode(encoding='ISO-8859-1')).decode(encoding='ISO-8859-1')  
 linko_final= f'<a href="data:file/csv;base64,{b64}" download={isim}>Download Analysed Data</a>'
 st.markdown(linko_final, unsafe_allow_html=True)  

this is how i have been using it on streamlit cloud
it is an hyperlink, not a button.
it just works fine and when clicked, it downloads dataframe in csv file format.

1 Like

This is what I do now that works on cloud, hope it might help someone else.
I’ve taken inspiration from all the different threads on the topic, and I create a button and when the user clicks the button a download link appears.

import base64
import io
import pandas as pd

def create_financial_report(df):
    output = io.BytesIO()
    writer = pd.ExcelWriter(output, engine='xlsxwriter')

    workbook = writer.book
    worksheet = workbook.add_worksheet('worksheet name')
    worksheet.write('A1', 'title of document')

    df.to_excel(writer, sheet_name='worksheet name', startrow=2, startcol=0)

    writer.close()

    return output.getvalue()

def get_xlsx_download_link(df):
    val = create_financial_report(df)
    b64 = base64.b64encode(val)
    return f'<a href="data:application/octet-stream;base64,{b64.decode()}" download="Financial_report.xlsx">Download file</a>'

df = pd.DataFrame(columns = ('a', 'b'), data = ([1, 2], [3,4]))
export_financial_report = export_area.button('Generate financial report')

if export_financial_report:
    export_area.markdown(output.get_xlsx_download_link(df), unsafe_allow_html=True)