Dynamic Reporting with R and ReporteRs

166 views Asked by At

I have a Shiny dashboard app that displays about 15 charts. I'm using ReporteRs to allow the user to download a powerpoint report containing the charts; one for each slide. I've now added some checkboxes for each chart and was wondering how I can make the report generation dynamic so if the user checked one chart, only one slide is produced; if they select two charts, two slides are produced, and so on.

Here's a simple example. I have two charts. If I deselect one on the download tab, how do I tell ReporteRs that I only want one slide with the chosen chart on it? If I then check both, ReporteRs produces two slides. My thinking is if I can solve this I just scale up to the required 15.

Thanks, Andrew

library(shiny)
library(ReporteRs)

# Define UI for application that draws a histogram
#ui <- fluidPage(

ui <- fluidPage(
  titlePanel("Powerpoint Report"),
  mainPanel(
    tabsetPanel(
      tabPanel(
        title = "Plots",
        solidHeader = FALSE,
        HTML("<br /><br /><br />"),
        fluidRow(
          column(width = 6,
                 plotOutput("barPlot1")
                 ),
          column(width = 6,
                 plotOutput("barPlot2")
                 )
          )
        ),
      tabPanel(
        title = "Download",
        solidHeader = FALSE,
        HTML("<br /><br /><br />"),
        checkboxGroupInput("down", "Select Charts",
                     choices = c("Cars Plot" = 1, "Iris Plot" = 2),
                     selected = list(1, 2)),
        HTML("<br /><br />"),
        downloadButton("download", "Download Powerpoint Report")
        )
      )
    )
  )

server <- function(input, output) {


  car <- function(){plot(cars$speed, cars$dist)}

  output$barPlot1 <- renderPlot(
    car()
  )

  iri <- function(){plot(iris$Sepal.Length, iris$Petal.Length)}


  output$barPlot2 <- renderPlot(
    iri()
  )

  output$download <- downloadHandler(
    file = "charts.pptx",
    content = function(file){
      doc = pptx( )
      doc <- addSlide(doc, "Title Slide")
      doc <- addTitle(doc,"How many Charts?")

      doc <- addSlide(doc, "Two Content")
      doc <- addTitle(doc,"Car Charts?")
      doc <- addPlot(doc, fun = function() car())

      doc <- addSlide(doc, "Two Content")
      doc <- addTitle(doc, "Iris Plot")
      doc <- addPlot(doc, fun = function() iri())

      writeDoc(doc, file)
    }
  )

}

# Run the application 
shinyApp(ui = ui, server = server)
1

There are 1 answers

0
SBista On

You could put if condition in downloadHandler like this:

server <- function(input, output) {


  car <- function(){plot(cars$speed, cars$dist)}

  output$barPlot1 <- renderPlot(
    car()
  )

  iri <- function(){plot(iris$Sepal.Length, iris$Petal.Length)}


  output$barPlot2 <- renderPlot(
    iri()
  )

  output$download <- downloadHandler(
    file = "charts.pptx",
    content = function(file){
      doc = pptx( )
      doc <- addSlide(doc, "Title Slide")
      doc <- addTitle(doc,"How many Charts?")

      if(any(isolate(input$down) == 1)){
        doc <- addSlide(doc, "Two Content")
        doc <- addTitle(doc,"Car Charts?")
        doc <- addPlot(doc, fun = function() car())
      }

      if(any(isolate(input$down) == 2)){
        doc <- addSlide(doc, "Two Content")
        doc <- addTitle(doc, "Iris Plot")
        doc <- addPlot(doc, fun = function() iri())
      }


      writeDoc(doc, file)
    }
  )

}