Search code examples
rshinydownloadformattable

Download formattable as excel R Shiny?


This downloading objects in R shiny is really giving me a headache, even tho it seemed too simple but I don't know how to keep on going. This question is meant for downloading a formattable output as an excel table, but I'm not even sure if they are compatible, or an image might do just fine. In here it seems like something to be done as I coded it, but every dowloadButton question for plotting has plot input separated from the output, as I set it up, but it isn't working as I thougth it would so I can't even go ahead and check if my dowloadButton will work. Any ideas or paths to follow would totally be appreciated!

library(openxlsx)
library(shiny)
library(formattable)

ui <- fluidPage(

  fluidRow(
    sidebarPanel(
      hr(style="border-color: #606060;"),
      # Add bullets
      h3(HTML(paste0("<b>","Download","</b>"))),
      downloadButton(outputId = "table_dowload", 
                     label = "Download"),
      hr(style="border-color: #606060;"),
      width = 3
    ),
    mainPanel(
      br(),
      formattableOutput("info_company_table"),
      br()
    )
  )
)

server <- function(input, output, session) {

## Visualization input
table_input <- function(){

  bycompany <- structure(list(Parent = "Melissa", 
                              Active = 12681L, 
                              Claims = 16.22, 
                              Strength = 24.15, 
                              Backward = 6.37, 
                              Forward = 1.09), 
                         row.names = 1L, 
                         class = "data.frame")

  # Visualize top 10
  if(nrow(bycompany())>0) {
    t <- formattable(bycompany() %>%
                       arrange(desc(`Active`, )) %>%
                       slice(1:10),
                     align = "l",
                     list(
                       `Backward` = color_tile("white", "lightblue"),
                       `Forward` = color_tile("white", "lightblue"),
                       `Claims` = color_tile("white", "lightblue"),
                       `Strength` = color_tile("white", "lightblue"),
                       `Active` = color_tile("white", "lightblue")
                     ))
  } else {
    t <- formattable(data.frame())
  }

}

## Visualization 
output$table <- renderFormattable({

  table_input()

})

# DOWNLOAD

output$table_dowload <- downloadHandler(
  filename <- function(){
  paste("Table",
        Sys.Date(),
        "xlsx",
        sep = ".")
},
content = function(file) {
  write.xlsx(table_input(), file)
})

}
shinyApp(ui,server)

Solution

  • You have multiple questions inside your question. First, let's address the download button and formattable which is not visualized in your main panel. Your download button is not working because on your server-side you defined your data frame bycompany as a function (bycompany()) therefore shiny does not recognize bycompany as data frame. So in order for your download button to work change (inside table_input function) all bycompany() to bycompany.

    So your code looks like this, and now download button works:

    library(openxlsx)
    library(shiny)
    library(formattable)
    # I've also added dplyr for pipe operator
    library(dplyr)
    ui <- fluidPage(fluidRow(
      sidebarPanel(
        hr(style = "border-color: #606060;"),
        # Add bullets
        h3(HTML(paste0(
          "<b>", "Download", "</b>"
        ))),
        downloadButton(outputId = "table_dowload",
                       label = "Download"),
        hr(style = "border-color: #606060;"),
        width = 3
      ),
      mainPanel(br(),
                formattableOutput("info_company_table"),
                br())
    ))
    
    server <- function(input, output, session) {
      ## Visualization input
      table_input <- function() {
        bycompany <- structure(
          list(
            Parent = "Melissa",
            Active = 12681L,
            Claims = 16.22,
            Strength = 24.15,
            Backward = 6.37,
            Forward = 1.09
          ),
          row.names = 1L,
          class = "data.frame"
        )
    
        # Visualize top 10
        if (nrow(bycompany) > 0) {
          t <- formattable(
            bycompany %>%
              arrange(desc(`Active`,)) %>%
              slice(1:10),
            align = "l",
            list(
              `Backward` = color_tile("white", "lightblue"),
              `Forward` = color_tile("white", "lightblue"),
              `Claims` = color_tile("white", "lightblue"),
              `Strength` = color_tile("white", "lightblue"),
              `Active` = color_tile("white", "lightblue")
            )
          )
        } else {
          t <- formattable(data.frame(t))
        }
    
      }
    
      ## Visualization
      output$table <- renderFormattable({
        table_input()
    
      })
    
      # DOWNLOAD
    
      output$table_dowload <- downloadHandler(
        filename <- function() {
          paste("Table",
                Sys.Date(),
                "xlsx",
                sep = ".")
        },
        content = function(file) {
          write.xlsx(table_input(), file)
        }
      )
    
    }
    shinyApp(ui, server)
    

    Also note, that if you would like to visualize formattable in your main panel, you should change this part

     ## Visualization
      output$table <- renderFormattable({
        table_input()
    
      })
    

    To this, as you have defined your UI part as formattableOutput("info_company_table")

              ## Visualization
              output$info_company_table <- renderFormattable({
                table_input()
    
              })
    

    Regarding formattable (i.e. the format of exported excel data) I could only found this link (which does not bring solution) https://github.com/renkun-ken/formattable/issues/70