如何在浏览器新标签页打开Shiny中downloadHandler生成的HTML文件?
解决Shiny生成HTML报告后在新浏览器标签页打开的问题
我完全理解你的需求:你希望在Shiny应用里生成计算后的HTML报告,直接在浏览器新标签页打开,而不是让用户下载或者在Shiny内部标签展示。原来用downloadHandler的方式只能触发文件下载,没法直接实现打开新标签页的效果,我们可以换个思路来搞定这个问题,下面是具体的解决方案:
核心思路
- 把
downloadButton换成普通的actionButton——我们不需要触发下载,而是要触发报告生成+打开的动作 - 把HTML报告生成到Shiny可以访问的路径:这里用临时目录,再通过
addResourcePath让Shiny能识别这个目录的资源 - 报告生成完成后,通过Shiny的消息机制告诉前端JavaScript打开报告的URL
修改后的完整代码
Shiny应用代码
library(shiny) library(rmarkdown) library(here) ui = fluidPage( sliderInput("slider", "Slider", 1, 100, 50), actionButton("generate_report", "Generate & Open Report"), # 用来接收后端消息并打开新标签页的JS代码 tags$script(HTML(" Shiny.addCustomMessageHandler('open_report', function(url) { window.open(url, '_blank'); }); ")) ) server = function(input, output, session) { # 注册临时目录为Shiny的资源路径,让前端能访问里面的文件 temp_dir <- tempdir() addResourcePath("report_temp", temp_dir) observeEvent(input$generate_report, { # 把Rmd模板复制到临时目录 tempReport <- file.path(temp_dir, "report.Rmd") file.copy(here("report.Rmd"), tempReport, overwrite = TRUE) # 设置要传递给Rmd的参数 params <- list(n = input$slider) # 生成HTML报告到临时目录 output_file <- file.path(temp_dir, "report.html") rmarkdown::render(tempReport, output_file = output_file, params = params, envir = new.env(parent = globalenv())) # 构造报告的访问URL,发送给前端打开新标签页 report_url <- sprintf("%s//%s/report_temp/report.html", session$clientData$url_protocol, session$clientData$url_hostname) session$sendCustomMessage("open_report", report_url) }) } shinyApp(ui = ui, server = server)
对应的report.Rmd代码
--- title: "Dummy Report" author: "John Doe " date: "April 13, 2019" output: html_document --- ```{r setup, include=FALSE} knitr::opts_chunk$set(echo = TRUE)
R Markdown
This is an R Markdown document. Markdown is a simple formatting syntax for authoring HTML, PDF, and MS Word documents.
When you click the Generate button a document will be generated that includes both content as well as the output of any embedded R code chunks within the document. You can embed an R code chunk like this:
summary(cars)
Including Plots
You can also embed plots, for example:
plot(pressure)
Note that the echo = FALSE parameter was added to the code chunk to prevent printing of the R code that generated the plot.
### 代码解释 - **UI部分**:替换了按钮类型,同时添加了一段JavaScript代码,专门用来接收后端发送的URL消息,并用`window.open`在新标签页打开。 - **Server部分**: - `addResourcePath`把临时目录注册成Shiny可访问的资源路径,这样前端能通过`/report_temp/`路径访问里面的文件。 - `observeEvent`监听按钮点击,完成Rmd复制、参数传递、HTML报告生成的全流程。 - 最后构造报告的完整访问URL,通过`session$sendCustomMessage`把URL传给前端,触发新标签页打开动作。 ### 注意事项 - 确保`report.Rmd`文件放在Shiny应用的工作目录下(可以用`here()`确认当前路径)。 - 部署到shinyapps.io时这个方案同样有效,服务器上的`tempdir()`能正常使用,`addResourcePath`的机制在部署环境中也能正常工作。 内容的提问来源于stack exchange,提问作者Mukul Mehta
相关产品推荐
相关产品推荐

