How to download file in streamlit

No worries :slight_smile: happy to help!

1 Like

@czubert Hi again mate, is there way to able the user download a file with xlsx extension?

yes, you can change “f’{file_name}.csv’” into “f’{file_name}.xlsx” , in that way, you can download xlsx file.

@BeyondMyself I tried this but when i press the button to download, and go to excel to open the file, i get a error saying the file are corrupted or are in different extension

tmp_download_link = download_button(cg_result_dataframe, f'cg_result_dataframe.xlsx', button_text='Donwload Cg Dataframe 💾')

and the code @czubert make available, only let the user download the file in csv or txt extension. As shows here:

 """
    Generates a link to download the given object_to_download.
    Params:
    ------
    object_to_download:  The object to be downloaded.

    download_filename (str): filename and extension of file. e.g. mydata.csv,
    some_txt_output.txt 

    download_link_text (str): Text to display for download
    link.

    button_text (str): Text to display on download button (e.g. 'click here to download file')

    pickle_it (bool): If True, pickle file.
    Returns:
    -------
    (str): the anchor tag to download object_to_download
    Examples:
    --------
    download_link(your_df, 'YOUR_DF.csv', 'Click to download data!')
    download_link(your_str, 'YOUR_STRING.txt', 'Click to download text!')
    """

As you may see in the download_button function, there is an if alse statement if picle_it, inside else statement there is another if else statement in which it checks the distance.

        elif isinstance(object_to_download, pd.DataFrame):
            object_to_download = object_to_download.to_csv(index=False)

you can see that there is written that if instance is pd.DataFrame, then you should use method ‘to_csv’
you need to change it to: pd.dataframe.to_excel() for more info check it here:pandas.DataFrame.to_excel — pandas 1.2.4 documentation

I hope it will work for you :slight_smile:

1 Like

I did those changes you said but didn’t worked. Instead, returned the following error:

elif isinstance(object_to_download, pd.DataFrame):
     object_to_download = object_to_download.to_excel(index=False)

i also changed the donwload_button extesion:

tmp_download_link = download_button(cg_result_dataframe, f'cg_result_dataframe.xlsx', button_text='Donwload Cg Dataframe 💾')

Try to do this:

hope it will help :slight_smile:

How can I download Image . I didn’t get that.
please anyone can provide code for that. @czubert

I just now saw this thread. Maybe this post from me could be of help?

Did @jgieseler solution work for you? :speak_no_evil:

@Bhavya_Soni try this

I also face this problem, and need a good solution.
I tried the solution of like this:

with open(zip_path, “rb”) as f:
bytes = f.read()
    b64 = base64.b64encode(bytes).decode()
    href = f'<a href="data:file/zip;base64,{b64}" download=\'{filename}.zip\'>\
        Click to download\
    </a>'
st.sidebar.markdown(href, unsafe_allow_html=True)

this solution will report RuntimeError:Data of size 280MB exceeds write limit of 50MB.

related topic link:

How to download file in streamlit - Using Streamlit - Streamlit

Hey all :wave:,

We now have Download Button natively supported in Streamlit via the 0.88.0 release with st.download_button!

To use, upgrade to the latest version:
pip install --upgrade streamlit

Helpful links:

Looking forward to hearing what you think :balloon:

2 Likes

Hey streamlit team,

Great feature! Looks much more clean and allowed me to even remove some lines of code!

Thanks a lot!

1 Like

Hi, I am using similar function however when I call the function, along with the Download CSV hyperlink, I also get the None. Any idea how I can fix this?

def get_table_download_link(df):
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # some strings <-> bytes conversions necessary here
href = f’Download csv file
return st.write(href, unsafe_allow_html=True)

Here is the image.
image

Thanks for the answer it worked perfectly. Is it possible to send the bin_str in a mail as a hyperlink? I tried but was only able to get to display the wanted text with HTML but it was not clickable

My code is:

def send_email(email_address, download_link):
  sender_email = ""
  password = ""
  msg = MIMEMultipart("alternative")
  msg["Subject"] = "Your results are in!"
  msg["From"] = sender_email
  msg["To"] = email_address
  html_line ="""<html> random text {download_link}</html>""".format(download_link=download_link)
  print(download_link)
  part = MIMEText(html_line, "html")
  msg.attach(part)
  context = ssl.create_default_context()
  with smtplib.SMTP_SSL("smtp.gmail.com", 465, context=context) as server:
      server.login(sender_email, password)
      server.sendmail(
          sender_email, email_address, msg.as_string()
      )

download_link is the whole href output from get_binary_file_downloader_html

st.write("Preview")
#openCV image result cropped_image which is an np array
st.image(cropped_image)
#cropped_image converted to PIL image color      
result = Image.fromarray(cropped_image.astype('uint8'), 'RGB')
    
img = Image.open(result)            

btn = st.download_button(
      label="Download image",
      data=img,
      file_name="imagename.png",
      mime="image/png")

I want to use st.download_button to download the image result I know I cannot no use the cropped_image result since an np array. I converted the image array to a PIL image but I don’t know what I need to do from here to get the result image filename or how to pass the result image to the st.download_button. Could anyone please give me some ideas how to solve this issue.

Hi, this is not working for me. when I debug I seem to get error in the line csv = df.to_csv(index=False), where when i print csv it returns none

Thanks for sharing this, this indeed was helpful!