0

I would like to download rhandsontable output object from an R Shiny app into .xlsx and .pdf format. Does anyone have any idea how to do this? For example, I want to download the tables in the results tab in the app below (the codes are copied from my other question earlier):

library(shiny)
library(rhandsontable)

ui <- navbarPage("App",
                 
                 tabPanel("Input",
                          numericInput('num_of_table', "Number of sub tabs: ", value = 1, min = 1, max = 10),
                          uiOutput("input")),
                 
                 tabPanel("Results",
                          uiOutput("results"))
                 
)

server <- function(input, output,session) {
  
  ### Input ### 
  input_table <- reactive({
    list_of_input_table = list()
    
    for (i in c(1:input$num_of_table)){
      mat <- matrix(c(1:25) * i, ncol = 5, nrow = 5)
      list_of_input_table[[i]] = as.data.frame(mat)
    }
    
    index = c(1:i)
    list_of_input_table[index]
  })
  
  observeEvent(input$num_of_table, {
    lapply(seq_len(input$num_of_table), function(i) {
      output[[paste0('input_table_', i)]] <- renderRHandsontable({
        rhandsontable(input_table()[[i]])
      })
    })
  })
  
  output$input <- renderUI({
    
    nTabs = input$num_of_table
    
    myTabs1 = lapply(seq_len(nTabs), function(x){
      tabPanel(paste("Tab", x),
               column(12,
                      rHandsontableOutput(paste0("input_table_", x))))
    })
    do.call(tabsetPanel, myTabs1)
    
  })
  
  ### Results ###
  results_table <- reactive({
    
    list_of_results_table = list()
    for (i in c(1:input$num_of_table)){
      req(input[[paste0("input_table_", i)]])
      list_of_results_table[[i]] <- hot_to_r(input[[paste0("input_table_", i)]])[2:5]/hot_to_r(input[[paste0("input_table_", i)]])[1:4]
      }
    return(list_of_results_table)
  })
  
  
  observeEvent(input$num_of_table, {
    lapply(seq_len(input$num_of_table), function(i) {
      output[[paste0('results_table_', i)]] <- renderRHandsontable({
        
        rhandsontable(results_table()[[i]])
      })
    })
  })
  
  output$results <- renderUI({
    
    nTabs = input$num_of_table
    
    myTabs2 = lapply(seq_len(nTabs), function(x){
      tabPanel(paste("Tab", x),
               column(12,
                      rHandsontableOutput(paste0("results_table_", x))))
    })
    do.call(tabsetPanel, myTabs2)
    
  })
}


shinyApp(ui,server)

Appreciate any help! Thanks!

debster
  • 333
  • 2
  • 10

1 Answers1

0

This will download the results but you will need to first click all the tabs in the results to essentially have the results rhandsontables active and then hit the downloadButton which you can also change to a downloadLink().

library(shiny)
library(rhandsontable)
library(writexl)

ui <- navbarPage("App",
                 
                 tabPanel("Input",
                          numericInput('num_of_table', "Number of sub tabs: ", value = 1, min = 1, max = 10),
                          uiOutput("input")
                          ),
                 
                 tabPanel("Results",
                          downloadButton("dwnld", "Download Results"),
                          uiOutput("results"))
                 
)

server <- function(input, output,session) {
  
  ### Input ### 
  input_table <- reactive({
    list_of_input_table = list()
    
    for (i in c(1:input$num_of_table)){
      mat <- matrix(c(1:25) * i, ncol = 5, nrow = 5)
      list_of_input_table[[i]] = as.data.frame(mat)
    }
    
    index = c(1:i)
    list_of_input_table[index]
  })
  
  observeEvent(input$num_of_table, {
    lapply(seq_len(input$num_of_table), function(i) {
      output[[paste0('input_table_', i)]] <- renderRHandsontable({
        rhandsontable(input_table()[[i]])
      })
    })
  })
  
  output$input <- renderUI({
    
    nTabs = input$num_of_table
    
    myTabs1 = lapply(seq_len(nTabs), function(x){
      tabPanel(paste("Tab", x),
               column(12,
                      rHandsontableOutput(paste0("input_table_", x))))
    })
    do.call(tabsetPanel, myTabs1)
    
  })
  
  
  
  ### Results ###
  results_table <- reactive({
    
    list_of_results_table = list()
    for (i in c(1:input$num_of_table)){
      req(input[[paste0("input_table_", i)]])
      list_of_results_table[[i]] <- hot_to_r(input[[paste0("input_table_", i)]])[2:5]/hot_to_r(input[[paste0("input_table_", i)]])[1:4]
    }
    return(list_of_results_table)
  })
  
  
  observeEvent(input$num_of_table, {
    lapply(seq_len(input$num_of_table), function(i) {
      output[[paste0('results_table_', i)]] <- renderRHandsontable({
        
        rhandsontable(results_table()[[i]])
      })
    })
  })
  
  output$results <- renderUI({
    
    nTabs = input$num_of_table
    
    myTabs2 = lapply(seq_len(nTabs), function(x){
      tabPanel(paste("Tab", x),
               column(12,
                      rHandsontableOutput(paste0("results_table_", x))))
    })
    do.call(tabsetPanel, myTabs2)
    
  })
  
  output$dwnld <- downloadHandler(
    filename = function(){ paste0("results.xlsx")},
    content = function(file){
      resultslist <- lapply(1:input$num_of_table, function(x) hot_to_r(input[[paste0("results_table_",x)]]))
      write_xlsx(resultslist, path = file)
    }
  )
  
}


shinyApp(ui,server)

zimia
  • 930
  • 3
  • 16