Reputation: 525
I am new to Shiny and I have created a really simple shiny app:
library(shiny)
ui <- fluidPage(
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
output$dto <- renderDataTable({MYTABLE})
}
runApp(list(ui=ui,server=server))
Is there any way to put an option to download the result of the table (doesn't matter if is CSV, XLSX...)
cheers
Upvotes: 19
Views: 31387
Reputation: 86
I have to execute the app in the browser because the filename isn't working. I use
runApp(list(ui=ui,server=server),launch.browser = T)
and it works perfectly for me.
If you don't want to use launch.browser=TRUE
you can write the filename and the extension for example .csv at the end of the filename when you use the download button in the shiny app.
Upvotes: 1
Reputation: 108543
That's pretty easy with downloadButton()
or downloadLink()
in combination with downloadHandler
if you make the data itself a reactive expression. Then you can download whatever you send to output using the same reactive expression.
A small example:
library(shiny)
ui <- fluidPage(
# This one is linked by the id 'download'
downloadButton('download',"Download the data"),
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
# Reactive expression with the data, in this case iris
thedata <- reactive(iris)
output$dto <- renderDataTable({thedata()})
output$download <- downloadHandler(
filename = function(){"thename.csv"},
content = function(fname){
write.csv(thedata(), fname)
}
)
}
runApp(list(ui=ui,server=server))
Keep in mind:
content
of downloadHandler
must be a function producing a file! It should take one argument for the connection/file name. In this example it is a csv file, but for eg images you can use png()
and dev.off()
, for ggplots you can use ggsave()
, ...filename
does not have to be a function, but I found it works
better that way. Especially when working with reactive expressions for the file name.downloadHandler
and the downloadButton
through the output list: the id of downloadButton
is the name of the output element returned by downloadHandler
.EDIT:
Some people try to use download.file()
for this, but that's wrong as well. The function download.file()
works when used on the user side, not the server side. It lets you download files from the internet to the computer that is calling the function. If you'd use that in a Shiny application, it would work when run locally. That's because user and server are the same machine. However, when deploying your app on a Shiny Server, download.file()
would essentially be downloading files TO the server, not from.
Upvotes: 31
Reputation: 2100
A slightly alternative solution based directly on the datatable
/ DT
extension buttons
.
I am shamelessly borrowing the example data from Joris...
library(shiny)
library(DT)
ui <- fluidPage(
# This one is linked by the id 'download'
fluidRow(column(7,dataTableOutput('dto')))
)
server <- function(input,output){
# Reactive expression with the data, in this case iris
thedata <- reactive(iris)
#the extensions parameter coupled with the options list does the trick
output$dto <- renderDataTable(thedata(), extensions = 'Buttons',
options = list(dom = 'Bfrtip',
buttons = c('copy', 'csv', 'excel', 'pdf', 'print'))
)
}
runApp(list(ui=ui,server=server), launch.browser=TRUE) #now runs by default in the external browser.
This will work with different outputs and personally I like the cleaner look. Just make sure that you are running the demo in the external browser. Otherwise it won't work.
Upvotes: 15