Open AlexisMayer opened 1 year ago
Thanks for the great question. There are probably a few ways to do this, but an easy one is to use openpyxl
to write to a tempfile:
from shiny import App, Inputs, Outputs, Session, ui
from openpyxl import Workbook
import tempfile
data = [["Name", "Age"], ["Alice", 28], ["Bob", 35], ["Charlie", 42]]
app_ui = ui.page_fluid(
ui.download_button("downloadData", "Download"),
)
def create_excel_file():
# It's important to use a tempfile so that user sessions do not conflict with
# one another.
with tempfile.NamedTemporaryFile(suffix=".xlsx", delete=False) as temp_file:
# Create a new Excel workbook
workbook = Workbook()
sheet = workbook.active
for row_data in data:
sheet.append(row_data)
# Save the workbook to the temporary file
workbook.save(temp_file.name)
# We return the file name so that it can be
return temp_file.name
def server(input: Inputs, output: Outputs, session: Session):
@session.download(filename="out.xlsx")
def downloadData():
file = create_excel_file()
return str(file)
app = App(app_ui, server)
I think you could also do this by yielding bytes, but in my testing I couldn't quite get this to work. @wch do you have any thoughts?
@session.download(filename="image.png")
def download2():
# Another way to implement a file download is by yielding bytes; either all at
# once, like in this case, or by yielding multiple times. When using this
# approach, you should pass a filename argument to @session.download, which
# determines what the browser will name the downloaded file.
x = np.random.uniform(size=input.num_points())
y = np.random.uniform(size=input.num_points())
plt.figure()
plt.scatter(x, y)
plt.title(input.title())
with io.BytesIO() as buf:
plt.savefig(buf, format="png")
yield buf.getvalue()
I had tried things around openpyxl but I was missing tempfile... Thank you very much for your answer and for your amazing work on the package.
You should take a look at the DT package available on R which allows you to do very nice things with Shiny. Look at the Button extension here: https://rstudio.github.io/DT/extensions.html
Good day !
Glad it worked! We're definitely working on something similar to the datatables package. These will eventually be built around the data grid output, and should give us a lot more flexibility.
@GShotwell Do you have a repro of the yielding bytes not working? That approach would be ideal, it gives us a natural way to clean up the temp .xlsx file after it's served to the client.
Hello, is it possible to recover an excel file (xlsx) through a download button? I only managed to get a csv through...