如何在Shiny中通过上传Rmd模板与数据生成并下载HTML报告
修复Shiny应用临时文件路径问题,实现自定义Rmd模板+数据生成报告
我需要开发一个Shiny应用,允许用户上传自定义Rmd模板和带x、y列的txt数据文件,生成并下载HTML报告。应用部署在公网,采用临时上传方式避免未授权访问模板和数据,但当前代码因临时文件路径错误无法运行。
原代码核心问题
- 临时模板路径构造错误:使用
input$templatefile$datapath(完整临时路径)拼接tempdir(),生成无效嵌套路径 - 错误将数据文件覆盖到模板路径,破坏Rmd模板文件
- 缺少文件上传有效性校验,未上传文件时点击按钮会触发报错
修正后的完整app.R代码
library(shiny) library(shinydashboard) library(shinyFiles) library(magrittr) ui <- dashboardPage( dashboardHeader(title="App"), dashboardSidebar(disable = TRUE), dashboardBody( fluidRow(box( # 数据文件上传 fileInput( inputId="inputfile", label="选择.tab分隔的.txt文件:", multiple = FALSE, accept=".txt" ), # 小数分隔符选择 selectInput( inputId="separator", label="选择小数分隔符:", choices=c( "逗号"=",", "点"="." ), selected="." ), # Rmd模板上传 fileInput( inputId="templatefile", label="选择Rmd模板文件:", multiple = FALSE, accept=".rmd" ) )), br(), fluidRow( column( width=6, align="right", downloadButton( "report", "生成报告" ) ) ) ) ) server <- function(input, output) { output$report <- downloadHandler( filename = "report.html", content = function(file) { # 校验用户是否已上传必要文件 req(input$inputfile, input$templatefile) # 构造临时模板文件路径:使用原模板文件名,避免路径嵌套错误 temp_report_path <- file.path(tempdir(), input$templatefile$name) # 将上传的模板复制到临时目录的正确路径 file.copy(input$templatefile$datapath, temp_report_path, overwrite = TRUE) # 渲染报告,直接使用上传数据的临时路径 rmarkdown::render( input = temp_report_path, output_file = file, envir = new.env(parent = globalenv()), params = list( inputfile = input$inputfile$datapath, separator = input$separator ) ) } ) } shinyApp(ui, server)
关键修改说明
- 修复临时路径构造:用
input$templatefile$name获取用户上传的模板文件名,结合tempdir()生成有效路径,避免原代码中路径嵌套的问题 - 移除错误的文件复制:不再将数据文件覆盖到模板路径,直接使用Shiny提供的
input$inputfile$datapath临时路径读取数据 - 添加输入校验:用
req()确保只有用户上传了数据和模板后,才执行报告生成逻辑,避免空值报错 - 指定输出文件:在
rmarkdown::render()中显式设置output_file = file,确保生成的报告直接写入下载文件
配套Rmd模板(可直接使用)
--- title: "Dummy report" output: html_document date: "`r Sys.Date()`" params: inputfile: label: "Select input data" input: file value: "test.txt" separator: label: "Select decimal separator" input: select value: "." choices: [",", "."] --- ```{r setup, include=FALSE} knitr::opts_chunk$set( echo = FALSE, message=FALSE, warning=FALSE) library(ggplot2)
# 读取数据 inputdata<-read.table( file=params$inputfile, header=TRUE, sep="\t", # 制表符分隔 dec=params$separator, fill = TRUE ) ggplot( data = inputdata, aes(x=x,y=y))+ geom_point()
内容的提问来源于stack exchange,提问作者Edd
相关产品推荐
相关产品推荐

