Asynchronous download PDF report.

Created by Ger InbergDecember 2018More apps by Ger

Asyc download
by Ger Inberg

show with app
library(shiny)
library(shinyjs)
library(ggplot2)
library(future)
library(promises)
library(ipc)
plan(multicore)

ui <- fluidPage(useShinyjs(),
                tags$head(tags$link(rel = "stylesheet", type = "text/css", href = "style.css")),
                HTML("<!-- common header-->
                 <div id='headerSection'>
                 <h1 style='color:white;'>Asynchronous download PDF report.</h1>
                 <span style='font-size: 1.2em'>
                 <span>Created by </span>
                 <a href='http://gerinberg.com'>Ger Inberg</a>
                 &bull;
                 <span>December 2018</span>
                 &bull;
                 <a href='http://gerinberg.com/shiny'>More apps</a> by Ger
                 </span>
                 </div>"),
                plotOutput("plot"),
                fluidRow(column(width = 6, tags$label(HTML("&zwnj;")), tags$br(), downloadButton("report", "Download report")),
                         column(width = 6, sliderInput("cylinders", "Minimum number of cylinders", value = 4, min = 4, max = 8))))

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

  body_content <- reactive({
    plot_content()
  })

  plot_content <- reactive({
    data <- mtcars[mtcars$cyl >= input$cylinders, ]
    ggplot(data, aes(x=cyl, y=mpg)) + geom_boxplot(aes(group=cyl)) + ggtitle("Miles per Gallon vs Number of Cylinders") + theme(plot.title = element_text(hjust = 0.5))
  })

  output$plot <- renderPlot({
    plot_content()
  })

  createReport <- function(body, filename) {
    # simulating expensive operation by a sleep
    Sys.sleep(20)
    pdf(file = filename)
    plot(body)
    dev.off()
  }

  output$report <- downloadHandler(
    filename = function() { "report.pdf" },
    content = function(file) {
      shinyjs::disable("report")
      result_val(NULL)
      body <- body_content()
      progress <- AsyncProgress$new(message = 'Creating report', detail = 'Please have some patience.')
      future({
        createReport(body, file)
        progress$close()
        return(1)
      }) %...>% result_val()
    }
  )
  observeEvent(result_val(), {
    shinyjs::enable("report")
  })
}
shinyApp(ui, server, options = list(display.mode = "showcase"))
#headerSection {
	margin: -20px 0 20px;
	color: #FAFAFA;
	padding: 10px 10px;
	box-shadow: 0 0 7px #000;
  background: gray;
} 
#headerSection a {
  color: white !important;
  text-decoration: underline;
}
Code license: MIT