Spaces:
Sleeping
Sleeping
File size: 3,336 Bytes
efbe6b4 |
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 |
import io
import re
import uuid
import base64
import streamlit as st
from typing import Optional, Union
from streamlit.elements.button import DownloadButtonDataType
DownloadButtonDataType = Union[DownloadButtonDataType, "pd.DataFrame", "Styler"]
HAS_PD = True
def download_button(label: str,
data: DownloadButtonDataType,
file_name: Optional[str] = None) -> str:
"""Generates a link to download the given data, support file-like object and pd.DataFrame.
Params
Args:
label: text show on page.
data: file-like object or pd.DataFrame.
file_name: filename and extension of file. e.g. mydata.csv,
Raises:
RuntimeError: when data type is not supported
Returns:
the anchor tag to download object_to_download
Examples:
download_button('Click to download data!', your_df, 'YOUR_DF.xlsx'),
download_button('Click to download text!', your_str.encode(), 'YOUR_STRING.txt')
"""
# inspired by https://gist.github.com/chad-m/6be98ed6cf1c4f17d09b7f6e5ca2978f
data_as_bytes: bytes
if isinstance(data, str):
data_as_bytes = data.encode()
elif isinstance(data, io.TextIOWrapper):
string_data = data.read()
data_as_bytes = string_data.encode()
# mimetype = mimetype or "text/plain"
# Assume bytes; try methods until we run out.
elif isinstance(data, bytes):
data_as_bytes = data
elif isinstance(data, io.BytesIO):
data.seek(0)
data_as_bytes = data.getvalue()
elif isinstance(data, io.BufferedReader):
data.seek(0)
data_as_bytes = data.read()
elif isinstance(data, io.RawIOBase):
data.seek(0)
data_as_bytes = data.read() or b""
elif HAS_PD and hasattr(data, "to_excel"):
bio = io.BytesIO()
data.to_excel(bio)
bio.seek(0)
data_as_bytes = bio.read()
else:
raise RuntimeError("Invalid binary data format: %s" % type(data))
b64 = base64.b64encode(data_as_bytes).decode()
button_uuid = str(uuid.uuid4()).replace("-", "")
button_id = re.sub(r"\d+", "", button_uuid)
custom_css = f"""
<style>
#{button_id} {{
background-color: rgb(255, 255, 255);
color: rgb(38, 39, 48);
padding: 0.4em 0.6em;
position: relative;
text-decoration: none;
border-radius: 4px;
border-width: 1px;
border-style: solid;
border-color: rgba(49, 51, 63, 0.2);
border-image: initial;
}}
#{button_id}:hover {{
border-color: rgb(246, 51, 102);
color: rgb(246, 51, 102);
}}
#{button_id}:active {{
box-shadow: none;
background-color: rgb(246, 51, 102);
color: white;
}}
</style> """
dl_link = (
custom_css
+ f'<a class="steDownloadButton" download="{file_name}" id="{button_id}" '
f'href="data:file/txt;base64,{b64}">{label}</a><br></br>'
)
div_dl_link = f"""<div class="row-widget stDownloadButton">{dl_link}</div>"""
st.markdown(div_dl_link, unsafe_allow_html=True)
return dl_link
|