I have created the following function for myself and use it frequently. It works fine for bigger files too, my files often have thousands of rows and so far I havenāt hit a limit yet.
def get_table_download_link(df):
"""Generates a link allowing the data in a given panda dataframe to be downloaded
in: dataframe
out: href string
"""
csv = df.to_csv(index=False)
b64 = base64.b64encode(csv.encode()).decode() # some strings <-> bytes conversions necessary here
href = f'<a href="data:file/csv;base64,{b64}">Download csv file</a>'
Heya, this works for me, but the files download without the .csv extension. Is there a way to make sure that the .csv extension occurs or specify the name of the csv file?
I havenāt found a way to do that automatically, but one can always edit the filename to filename.csv when saving the link with the right mouse click.
Why did U say that the file is downloaded without the .csv, itās not true if you have converted your dataframe with the to_csv() method. Itās works like a charm
Iāve been searching for a while, a way to do same thing with excel xlsx file. I finally found
a way to make it work, so I decide to share my code here. I hope it will help someone.
python 3, pandas '0.23.4'
import streamlit as st
import base64
from io import BytesIO
def to_excel(df):
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
df.to_excel(writer, sheet_name='Sheet1')
writer.save()
processed_data = output.getvalue()
return processed_data
def get_table_download_link(df):
"""Generates a link allowing the data in a given panda dataframe to be downloaded
in: dataframe
out: href string
"""
val = to_excel(df)
b64 = base64.b64encode(val) # val looks like b'...'
return f'<a href="data:application/octet-stream;base64,{b64.decode()}" download="extract.xlsx">Download csv file</a>' # decode b'abc' => abc
df = ... # your dataframe
st.markdown(get_table_download_link(df), unsafe_allow_html=True)
# PS: pip install xlsxwriter # pandas need this
This is a great answer for csv files or excel files.
However does it work on midi (*.mid) files? midi files are binary. like the excel files.
Now I dont think i need to encode/decode to b64. what do you think? if i do use the b64 enc/decoding i get
TypeError: a bytes-like object is required, not '_io.BufferedReaderā
if i dont it still doesnt work.
you can find an example midi file here example_midi
example:
import base64
def get_midi_download_link(mid):
"""Generates a link allowing the data in a given midi file to be downloaded
in: midi file
out: href string
"""
# val looks like b'...'
return f'<a href="data:application/octet-stream;{mid}" download="example.mid">Download midi file with save as</a>'
with open("105027.mid", 'rb') as inmidi:
st.markdown(get_midi_download_link(inmidi), unsafe_allow_html=True)
Hi, if I make an excel file downloadable and if my excel downloadable file values are in float of 4 decimal place, how to make it to 2 decimal place? i.e while download the file values should come with 2 decimal places.
import streamlit as st
import base64
from io import BytesIO
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'}) # Tried with '0%' and '#,##0.00' also.
worksheet.set_column('A:A', None, format1) # Say Data are in column A
writer.save()
processed_data = output.getvalue()
return processed_data
def get_table_download_link(df):
"""Generates a link allowing the data in a given panda dataframe to be downloaded
in: dataframe
out: href string
"""
val = to_excel(df)
b64 = base64.b64encode(val) # val looks like b'...'
return f'<a href="data:application/octet-stream;base64,{b64.decode()}" download="Your_File.xlsx">Download Excel file</a>' # decode b'abc' => abc
st.markdown(get_table_download_link(df), unsafe_allow_html=True)
Thank, I got the answer. Was supposed this: float_format="%.2f"
import streamlit as st
import base64
from io import BytesIO
def to_excel(df):
output = BytesIO()
writer = pd.ExcelWriter(output, engine='xlsxwriter')
df.to_excel(writer, index = False, sheet_name='Sheet1',float_format="%.2f")
writer.save()
processed_data = output.getvalue()
return processed_data
def get_table_download_link(df):
"""Generates a link allowing the data in a given panda dataframe to be downloaded
in: dataframe
out: href string
"""
val = to_excel(df)
b64 = base64.b64encode(val) # val looks like b'...'
return f'<a href="data:application/octet-stream;base64,{b64.decode()}" download="Your_File.xlsx">Download Excel file</a>' # decode b'abc' => abc
st.markdown(get_table_download_link(df), unsafe_allow_html=True)
Also, curious if anyone has any ideas about how to generalize file downloads in Streamlit. For example: CSV, Excel, img, txt, midi, pdf, video formats, etc.
It would also be neat to auto download on button click - or interaction with another Streamlit component - rather than a link being returned. Iāve started researching ways to achieve this, but itās admittedly not my specialty area. Any thoughts on how to achieve this?
import base64
import streamlit as st
import pandas as pd
def download_link(object_to_download, download_filename, download_link_text):
"""
Generates a link to download the given object_to_download.
object_to_download (str, pd.DataFrame): 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.
Examples:
download_link(YOUR_DF, 'YOUR_DF.csv', 'Click here to download data!')
download_link(YOUR_STRING, 'YOUR_STRING.txt', 'Click here to download your text!')
"""
if isinstance(object_to_download,pd.DataFrame):
object_to_download = object_to_download.to_csv(index=False)
# some strings <-> bytes conversions necessary here
b64 = base64.b64encode(object_to_download.encode()).decode()
Thanks for stopping by! We use cookies to help us understand how you interact with our website.
By clicking āAccept allā, you consent to our use of cookies. For more information, please see our privacy policy.
Cookie settings
Strictly necessary cookies
These cookies are necessary for the website to function and cannot be switched off. They are usually only set in response to actions made by you which amount to a request for services, such as setting your privacy preferences, logging in or filling in forms.
Performance cookies
These cookies allow us to count visits and traffic sources so we can measure and improve the performance of our site. They help us understand how visitors move around the site and which pages are most frequently visited.
Functional cookies
These cookies are used to record your choices and settings, maintain your preferences over time and recognize you when you return to our website. These cookies help us to personalize our content for you and remember your preferences.
Targeting cookies
These cookies may be deployed to our site by our advertising partners to build a profile of your interest and provide you with content that is relevant to you, including showing you relevant ads on other websites.