0

I am trying to work on a functioniality for our shiny app where in the user can download a powerpoint with all the tables and charts. I did see a standalone app where I know how to use it if all the tables and plots are in the server component. Since our code base is increasing and we are trying to use modules to break the app I am unable to identify where should I have the downloadhandler. If I have it in the server component how can I pass my tables and plots from the modules to this function in server. Below is the code of a standalone download to powerpoint code.

library(shiny)
library(officer)
library(flextable)
library(dplyr)

my_table <- data.frame(
  Name = letters[1:4],
  Age = seq(20, 26, 2),
  Occupation = LETTERS[15:18],
  Income = c(50000, 20000, 30000, 45000)
)

ui <- fluidRow(
  column(
    width = 12,
    align = "center",
    tableOutput("data"),
    br(),
    downloadButton("download_powerpoint", "Download Data to PowerPoint")
  )
)

server <- function(input, output) {
  output$data <- renderTable({
    my_table
  })

  output$download_powerpoint <- downloadHandler(
    filename = function() {  
      "employee_data.pptx"
    },
    content = function(file) {
      flextable_prep <- flextable(my_table) %>% 
        colformat_num(col_keys = c("Age", "Income"), digits = 0) %>% 
        width(width = 1.25) %>% 
        height_all(height = 0.35) %>% 
        theme_zebra() %>% 
        align(align = "center", part = "all")

      example_pp <- read_pptx() %>% 
        add_slide(layout = "Title Slide", master = "Office Theme") %>% 
        ph_with_text(
          type = "ctrTitle",
          str = "Employee Data"
        ) %>% 
        ph_with(
          location = ph_location_type(type = "subTitle"),
          value = "Company 2019 Report"
        ) %>% 
        add_slide(layout = "Title and Content", master = "Office Theme") %>% 
        ph_with_text(
          type = "title",
          str = "2019 Data"
        ) %>% 
        ph_with_flextable_at(
          value = flextable_prep,
          left = 2.5,
          top = 2
        )

      print(example_pp, target = file)
    }
  )
}

shinyApp(ui, server)
SNT
  • 1,283
  • 3
  • 32
  • 78
  • You can either return from the module and use the result or you assign to the session user data, see here:https://stackoverflow.com/a/58965308/3502164 – Tonio Liebrand Dec 08 '19 at 11:58

1 Answers1

1

There are several ways to pass data from a module to another.

You can for example return a reactive from one module, and use it in another.

See (I removed the powerpoint generation here to focus on the implementation of the reactivity) :

library(shiny)
library(officer)
library(flextable)
library(dplyr)

showui <- function(id){
  ns <- NS(id)
  tagList(
    selectInput(ns("table"), "table", choices = c("iris", "mtcars")),
    tableOutput(ns("data"))
  )
}

show <- function(input, output, session){
  ns <- session$ns

  my_table <- reactive({
    get(input$table)
  })

  output$data <- renderTable({
    head(my_table())
  })

  my_table
}


dlui <- function(id){
  ns <- NS(id)
  tagList(
    downloadButton(
      ns("download_powerpoint"), 
      "Download Data"
    )
  )
}

dl <- function(input, output, session, my_table){
  ns <- session$ns

  output$download_powerpoint <- downloadHandler(
    filename = function() {  
      "employee_data.csv"
    },
    content = function(file) {
      write.csv(my_table(), file)
    }
  )
}

ui <- fluidRow(
  column(
    width = 12,
    align = "center",
    showui("showui"),
    br(),
    dlui("dlui")
  )
)

server <- function(input, output) {

  my_table <- callModule(show, "showui")

  callModule(dl, "dlui", my_table)
}

shinyApp(ui, server)
Colin FAY
  • 4,849
  • 1
  • 12
  • 29
  • Thanks Colin. I used to do the download tables to powerpoint. I wasnt able to do that for adding a plotly plot to the powerpoint. Anyidea if that can be done. I can start as a new question else. – SNT Dec 10 '19 at 17:34
  • As plotly is interactive, it's hard to capture it as a powerpoint. You might want to try https://plot.ly/r/static-image-export/ – Colin FAY Dec 11 '19 at 09:05