My app is 99% of the way there, but at the end I want the user to download the .xlsx file that I created. I am having a lot of trouble with the download button, however. I excerpt a snippet of code below and then show the error. Just so you know, I have tried creating the xlsx WITH specifying encoding (like below) and WITHOUT and it doesn’t seem to make any difference. The issue appears to be that when streamlit “reads” the filestream it cannot do so due to an encoding issue. The other things I have tried are to: (i) specify encoding on the with open line like this:
with open('./outputs/summary.xlsx', mode='r', encoding="utf-8") as f:
But that doesn’t solve the problem. I have also tried opening the file as a bytestream with ‘rb’ and that WILL allow me to download something, but it is a BIN file.
Here’s the code:
import streamlit as st
from openpyxl import Workbook
from openpyxl.styles import Font, Alignment
class CreateWorkbook:
def __init__(self):
self.wb = Workbook()
self.wb.encoding="utf-8"
self.ws = self.wb.active
def create_workbook(self):
# Create column headers.
self.ws['A1'] = "Country".encode(encoding='utf-8')
self.ws['B1'] = "Article".encode(encoding='utf-8')
self.ws['C1'] = "Question".encode(encoding='utf-8')
self.ws['D1'] = "Answer".encode(encoding='utf-8')
# Bold the headers.
self.ws['A1'].font = Font(bold=True)
self.ws['B1'].font = Font(bold=True)
self.ws['C1'].font = Font(bold=True)
self.ws['D1'].font = Font(bold=True)
# Fill in the Data.
current_row = 2
for country, articles_frame in response_map.items():
for article, qa_frame in articles_frame.items():
for question, answer in qa_frame.items():
self.ws['A' + str(current_row)] = country.encode(encoding = 'utf-8', errors = 'replace')
self.ws['B' + str(current_row)] = article.encode(encoding = 'utf-8', errors = 'replace')
self.ws['C' + str(current_row)] = question.encode(encoding = 'utf-8', errors = 'replace')
self.ws['D' + str(current_row)] = answer.encode(encoding = 'utf-8', errors = 'replace')
current_row = current_row + 1
# Set Column Widths
self.ws.column_dimensions['A'].width = 30
self.ws.column_dimensions['B'].width = 20
self.ws.column_dimensions['C'].width = 80
self.ws.column_dimensions['D'].width = 80
# Ensure every Cell wraps text.
for row in self.ws.iter_rows():
for cell in row:
alignment = Alignment(wrap_text=True, vertical="top")
cell.alignment = alignment
self.wb.save('./outputs/summary.xlsx')
st.write(":balloon: :ballooon")
create_wb_object = CreateWorkbook()
create_wb_object.create_workbook()
with open('./outputs/summary.xlsx', mode='r', encoding="utf-8") as f:
st.download_button('Download', f)
Here’s the error:
2024-02-26 13:39:04.558 Uncaught app exception
Traceback (most recent call last):
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 535, in _run_script
exec(code, module.__dict__)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\main.py", line 56, in <module>
st.download_button('Download', f)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\metrics_util.py", line 397, in wrapped_func
result = non_optional_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 331, in download_button
return self._download_button(
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 580, in _download_button
marshall_file(
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 787, in marshall_file
string_data = data.read()
^^^^^^^^^^^
File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte
2024-02-26 13:39:04.624 Uncaught app exception
Traceback (most recent call last):
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 535, in _run_script
exec(code, module.__dict__)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\main.py", line 56, in <module>
st.download_button('Download', f)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\metrics_util.py", line 397, in wrapped_func
result = non_optional_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 331, in download_button
return self._download_button(
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 580, in _download_button
marshall_file(
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 787, in marshall_file
string_data = data.read()
^^^^^^^^^^^
File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte
2024-02-26 13:39:05.261 Uncaught app exception
Traceback (most recent call last):
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\scriptrunner\script_runner.py", line 535, in _run_script
exec(code, module.__dict__)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\main.py", line 56, in <module>
st.download_button('Download', f)
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\runtime\metrics_util.py", line 397, in wrapped_func
result = non_optional_func(*args, **kwargs)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 331, in download_button
return self._download_button(
^^^^^^^^^^^^^^^^^^^^^^
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 580, in _download_button
marshall_file(
File "C:\Users\mcdnj\PycharmProjects\Streamlit Experiment\.venv\Lib\site-packages\streamlit\elements\widgets\button.py", line 787, in marshall_file
string_data = data.read()
^^^^^^^^^^^
File "<frozen codecs>", line 322, in decode
UnicodeDecodeError: 'utf-8' codec can't decode byte 0xe2 in position 10: invalid continuation byte
Any thoughts???