在输出格式之间切换,同时从 Shiny 生成可下载的 RMarkdown 报告
Switching between output formats while generating downloadable RMarkdown reports from Shiny
我正在尝试使用 Shiny 生成可下载的 RMarkdown 报告。我在 UI 中包含了单选按钮,以允许用户 select 报告的输出格式(Word 或 PDF)。我面临的问题是 UI 中的格式 selection 不影响输出格式。 radioButton 语句中的第一个选择是指定输出格式,即当前列表中的第一个选择 choices=list("PDF", "Word")
设置为 PDF,无论 selected 是什么,都会生成 PDF 输出在 UI。同样,如果列表中的第一个选项设置为 Word choices=list("Word", "PDF")
,则 Word 文档就是最终输出,而不管 select 在 UI.[=14= 中编辑了什么]
我不确定自己做错了什么,所以非常感谢您的帮助!我在下面提供了一些虚拟代码。
闪亮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 模板
---
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)
}
```
我认为渲染文档的格式是选择的格式。只有文件名没有正确的扩展名。那是因为您在 downloadHandler
的 filename
参数中有一个反应变量 (input$format
)。在这种情况下,您必须使用 filename
的函数。即替换
filename = paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
和
filename = function(){
paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
}
我正在尝试使用 Shiny 生成可下载的 RMarkdown 报告。我在 UI 中包含了单选按钮,以允许用户 select 报告的输出格式(Word 或 PDF)。我面临的问题是 UI 中的格式 selection 不影响输出格式。 radioButton 语句中的第一个选择是指定输出格式,即当前列表中的第一个选择 choices=list("PDF", "Word")
设置为 PDF,无论 selected 是什么,都会生成 PDF 输出在 UI。同样,如果列表中的第一个选项设置为 Word choices=list("Word", "PDF")
,则 Word 文档就是最终输出,而不管 select 在 UI.[=14= 中编辑了什么]
我不确定自己做错了什么,所以非常感谢您的帮助!我在下面提供了一些虚拟代码。
闪亮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 模板
---
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)
}
```
我认为渲染文档的格式是选择的格式。只有文件名没有正确的扩展名。那是因为您在 downloadHandler
的 filename
参数中有一个反应变量 (input$format
)。在这种情况下,您必须使用 filename
的函数。即替换
filename = paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
和
filename = function(){
paste("report", switch(input$format, "Word"="docx", "PDF"="pdf"), sep=".")
}