I am trying to generate downloadable RMarkdown reports using Shiny. I have included radioButtons in the UI to allow the user to select the output format of the report (Word or PDF). The problem I am facing is that the format selection in the UI is not impacting the output format. The first choice in the radioButton statement is dictating the output format, i.e., currently the first choice in the list, choices=list("PDF", "Word")
, is set to PDF, this is producing a PDF output regardless of what is selected in the UI. Similarly, if the first choice in the list is set to Word, choices=list("Word", "PDF")
, then a Word document is the final output regardless of what is selected in the UI.
I am unsure what I doing wrong so I would really appreciate any help! I have provided some dummy code below.
Shiny UI/Server
# Load packages
suppressWarnings(suppressMessages(library(shiny)))
suppressWarnings(suppressMessages(library(tidyverse)))
suppressWarnings(suppressMessages(library(rmarkdown)))
suppressWarnings(suppressMessages(library(bookdown)))
suppressWarnings(suppressMessages(library(knitr)))
# Define data frame variables
countries = c("Canada", "United States of America", "Qatar", "Scotland", "Bangladesh")
capitals = c("Ottawa", "Washington, DC", "Doha", "Edinburgh", "Dhaka")
values = seq(1, 5, 1)
# Build data fram
df = data.frame(countries, capitals, values)
# User interface
ui = fluidPage(
# Define title for the app
titlePanel("Dummy example"),
# Sidebar layout with input and output definitions
sidebarLayout(
sidebarPanel(
selectInput("select_country", "Select Country:", choice = unique(df$countries)),
uiOutput("select_capital"),
radioButtons("format", "Summary Format:", choices=list("PDF", "Word"), inline=TRUE),
downloadButton("download_report", "Download Report")
),
mainPanel(
)
)
)
# Server logic
server = function(input, output, clientData, session) {
# Build capitals filter based on selected country
output$select_capital = renderUI({
df = df[df$countries == input$select_country, ]
choice = unique(df$capitals)
selectInput(
"select_capital",
"Select Capital:",
choices = choice
)
})
# Download report
output$download_report = downloadHandler(
filename = paste("report",
switch(input$format, "Word"="docx", "PDF"="pdf"), sep="."),
content = function(file) {
normalized_path = normalizePath("report.Rmd")
# Temporarily switch to a temp directory in case you do not have permission
# to the current working directory
owd = setwd(tempdir())
on.exit(setwd(owd))
file.copy(normalized_path, "report.Rmd", overwrite=TRUE)
# Set up parameters to pass to Rmd documents
params = list(countries = input$select_country,
capitals = input$select_capital,
format = input$format)
out = rmarkdown::render("report.Rmd",
switch(input$format, "PDF"=pdf_document(), "Word"=word_document()),
params=params,
envir=new.env())
file.rename(out, file)
}
)
}
# Run RShiny app
shinyApp(ui, server)
RMarkdown template
---
title: "Dummy example"
date: "`r format(Sys.time(), '%B %d, %Y')`"
output:
bookdown::pdf_document2:
toc: false
df_print: kable
extra_dependencies: ["float"]
bookdown::word_document2:
toc: false
classoption: twocolumn
params:
countries: NA
capitals: NA
format: NA
urlcolor: blue
always_allow_html: true
header-includes:
- \usepackage{booktabs}
- \usepackage{longtable}
- \usepackage{array}
- \usepackage{multirow}
- \usepackage{float}
- \usepackage{tabu}
---
```{r packages, echo=FALSE, eval=TRUE, message=FALSE, include=FALSE}
knitr::opts_chunk$set(fig.pos = "!H", out.extra = "")
# Load packages
library(tidyverse)
library(rmarkdown)
library(bookdown)
library(knitr)
library(flextable)
library(kableExtra)
```
```{r print-dataframe, echo=FALSE, eval=TRUE, message=FALSE, results="asis"}
# Print data frame
print(params$format)
if (params$format == "Word") {
# Use flextable if the output format is Word
flextable(df)
} else {
# Use kable if the output format if PDF
df = knitr::kable(df, booktabs=T, caption="Dummy example") %>%
kableExtra::kable_styling(latex_options=c("scale_down", "HOLD_position", "repeat_header"))
print(df)
}
```