Gompu
Gompu

Reputation: 425

Download table generated independently in renderTable output in R shiny

I am trying to generate a table using the renderTable function in R shiny and then use the downloadHandler function to download that table/data.frame as a csv file. Somehow I keep getting the following error:

An error occured during download: Error downloading http://127:0:0.1:3001/session/ 0303bd426fce88837ae277aa3b406dd/download/downloadData?w= - server replied: Internal Server Error

Below is an example code where I generate a simple data frame and try to download it using downloadHander:

library(shiny)
 # Define UI for data download app ----
ui <- fluidPage(

    # App title ----
    titlePanel("Downloading Data"),

    # Sidebar layout with input and output definitions ----
    sidebarLayout(

        # Sidebar panel for inputs ----
        sidebarPanel(
            # Button
            downloadButton("downloadData", "Download")

        ),

        # Main panel for displaying outputs ----
        mainPanel(

            tableOutput("table")

        )

    )
)
# Define server logic to display and download selected file ----
server <- function(input, output) {

    # Table of selected dataset ----
    output$table <- renderTable({
        data.frame(a =c(1,2,3),b=c("q","s","f"))
    })

    # Downloadable csv of selected dataset ----
    output$downloadData <- downloadHandler(
        filename = function() {
            paste("test.csv")
        },
        content = function(file) {
            write.csv(output$table, file, row.names = FALSE)
        }
    )

}
shinyApp(ui,server)

Upvotes: 1

Views: 3425

Answers (2)

RickTastic
RickTastic

Reputation: 300

There are a few things that need to be done here:

  1. If your app is going to render data dynamically, then your data should be assigned to some reactive expression.
  2. Now the downloading of the data becomes easy, as you just call the reactive expression written in (1).
    • Points (1) and (2) above will ensure that the user is downloading the same data that is seen on the screen.

Try the following:

library(shiny)

ui <- fluidPage(
  titlePanel("Downloading Data"),
  sidebarLayout(
    sidebarPanel(downloadButton("downloadData", "Download")),
    mainPanel(tableOutput("table"))
  )
)

server <- function(input, output) {

  data <- shiny::reactive(data.frame(a = c(1, 2, 3), b = c("q", "s", "f")))
  output$table <- renderTable(data())

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("test.csv")
    },
    content = function(file) {
      write.csv(data(), file, row.names = FALSE)
    }
  )

}
shinyApp(ui,server)

Upvotes: 5

Chabo
Chabo

Reputation: 3000

You cannot export a renderTable{} as this puts many of the elements into HTML, you need to previously save the data going into the table and export it seperately.

dataTable<-data.frame(a =c(1,2,3),b=c("q","s","f"))

output$downloadData <- downloadHandler(

  filename = function() {
    ('test.csv')
  }, 

  content = function(con) {
    write.table(dataTable,row.names = FALSE,col.names=T, sep=",",con)
  },
  contentType="csv"
)

Upvotes: 1

Related Questions