Search code examples
pythonexcelpandasstreamlitpandas.excelwriter

how to download excel file in python and streamlit?


I have a Python script that read files and convert it to dataframe using Python and streamlit. Then I want to create a function to allows the user to download this dataframe as an Excel file with extension .xls.

So I tried to read the dataframe and convert it to an Excel file using these two functions:

pd.ExcelWriter
df.to_excel

But when I try to download the file using a link the file doesn't download and displays this error:

Failed-Network error

Code:

import pandas as pd 
import streamlit as st

writer = pd.ExcelWriter('update2.xlsx')
df.to_excel(writer, index = False, header=True,encoding='utf-8')
with open(writer,'rb') as f:
    b64 = base64.b64encode(f.read())
    href = f'<a href="data:file/xls;base64,{b64}" download="new_file.{extension}">Download {extension}</a>'

st.write(href, unsafe_allow_html=True)

Solution

  • With the streamlit latest release(above 1.0.0):

    Use

    st.download_button
    

    Displays a download button widget.

    This is useful when you would like to provide a way for your users to download a file directly from your app.

    Note that the data to be downloaded is stored in memory while the user is connected, so it's a good idea to keep file sizes under a couple of hundred megabytes to conserve memory.

    Here is a sample code from the discussion, that can be helpful to download excel files...

    import pandas as pd
    from io import BytesIO
    from pyxlsb import open_workbook as open_xlsb
    import streamlit as st
    
    def to_excel(df):
        output = BytesIO()
        writer = pd.ExcelWriter(output, engine='xlsxwriter')
        df.to_excel(writer, index=False, sheet_name='Sheet1')
        workbook = writer.book
        worksheet = writer.sheets['Sheet1']
        format1 = workbook.add_format({'num_format': '0.00'}) 
        worksheet.set_column('A:A', None, format1)  
        writer.save()
        processed_data = output.getvalue()
        return processed_data
    df_xlsx = to_excel(df)
    st.download_button(label='📥 Download Current Result',
                                    data=df_xlsx ,
                                    file_name= 'df_test.xlsx')