Generating downloadable reports
After interacting with a Shiny application and getting it certain state, your users may want to download a report in HTML or PDF format. You can easily add the ability to generate a report with knitr and rmarkdown at the click of a button.
There are two key parts for this:
- A
downloadHandler()
which knits the document on demand and passes values to the document. - An R Markdown document which is parameterized.
Example
This app takes one input value, and passes it as a parameter to an .Rmd document, which is rendered (or knitted) into an HTML output file. You can see this app in action here.
app.R
:
```{r}
shinyApp(
ui = fluidPage(
sliderInput("slider", "Slider", 1, 100, 50),
downloadButton("report", "Generate report")
),
server = function(input, output) {
output$report <- downloadHandler(
# For PDF output, change this to "report.pdf"
filename = "report.html",
content = function(file) {
# Copy the report file to a temporary directory before processing it, in
# case we don't have write permissions to the current working dir (which
# can happen when deployed).
tempReport <- file.path(tempdir(), "report.Rmd")
file.copy("report.Rmd", tempReport, overwrite = TRUE)
# Set up parameters to pass to Rmd document
params <- list(n = input$slider)
# Knit the document, passing in the `params` list, and eval it in a
# child of the global environment (this isolates the code in the document
# from the code in this app).
rmarkdown::render(tempReport, output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
)
```
report.Rmd
:
---
title: "Dynamic report"
output: html_document
params:
n: NA
---
```{r}
# The `params` object is available in the document.
params$n
```
`params$n` random points.
A plot of
```{r}
plot(rnorm(params$n), rnorm(params$n))
```
Note that due to an issue in the rmarkdown package, the default value of a parameter in the YAML header cannot be NULL
, so we’ve used NA
as the default value of n
.
Notes
The rmarkdown::render()
function has many options to control the processing and output. See the rmarkdown website to learn more. Some commonly used options are described below.
By default, an HTML file generated by rmarkdown::render()
will have all plots and other images embedded directly in the HTML, so you can simply publish or send the HTML file, without needing to handle separate image files.
If you want PDF output, the rmarkdown::render()
function can do that. This will require two changes:
- Change the
filename
argument ofdownloadHandler()
to"report.pdf"
. - Use
output: pdf_document
in the YAML header of the Rmd file.
It will also require pdflatex to be installed on your system.
Another way to generate a PDF is to pass in a value to output_format
argument of rmarkdown::render()
, as demonstrated in this app.
To generate a Microsoft Word document:
- Change the
filename
argument ofdownloadHandler()
to"report.doc"
. - Use
output: word_document
in the YAML header of the Rmd file.
When calling rmarkdown::render
, it is possible for the Rmd document to directly access variables that are available to the Shiny app, including input values like input$slider
. This can be done by using the default value for envir
(instead of passing in a new environment). However, we recommend passing in params
and using a new envir
, because it provides better code isolation and makes things easier to debug.