闪亮的应用程序将无法从Chrome下载pdf_打印Rmd渲染

mbjcgjjk  于 12个月前  发布在  其他
关注(0)|答案(1)|浏览(101)

我正在按照https://github.com/RLesur/chrome_print_shiny的示例构建一个Shiny应用程序,它将从.Rmd文件生成.pdf输出。我可以让示例应用程序.R在本地运行(对于大多数选择),但修改最终将使用render(params())的.Rmd并不成功。

ReportGenerator.Rmd

---
title: "Test Report"
output:
  pagedown::html_paged:
    includes:
    number_sections: false
    self_contained: true
    css:
       - default

params:
  gonna: "a"
  have: "b"
  some: "c"
  later: "d"
#knit: pagedown::chrome_print # commented out for use in Shiny
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)

Summary

summary(cars)

Plot

plot(pressure)
字符串

**app.R**

library(pagedown)
library(promises)
library(rmarkdown)
library(shiny)
library(shinybusy)

chrome_extra_args <- function(default_args = c("--disable-gpu")) {
args <- default_args

Test whether we are in a shinyapps container

if (identical(Sys.getenv("R_CONFIG_ACTIVE"), "shinyapps")) {
args <- c(args,
"--no-sandbox", # required because we are in a container
"--disable-dev-shm-usage") # in case of low available memory
}
args
}

send the .Rmd to temp

tempReport <- tempfile(fileext=".Rmd")
file.copy("ReportGenerator.Rmd", tempReport, overwrite=TRUE)

ui <- fluidPage(
actionButton( # build the report
inputId="buildBtn",
label="Build Report"
),
uiOutput("downloadBtn") # download the report
)

server <- function(input, output) {
observeEvent(input$buildBtn, {
output$downloadBtn <- renderUI({
show_modal_spinner()
# generate PDF
chrome_print(
render(tempReport,
# will have params here later
envir = new.env(parent = globalenv())
),
output=tempfile(fileext=".pdf"),
extra_args=chrome_extra_args(),
verbose=1,
async=TRUE
)$then(
onFulfilled=function(value){
showNotification("PDF file successfully generated", type="message")
output$downloadBtn <- downloadHandler(
filename="Report.pdf",
content=function(file){
file.copy(value, file) # I think the problem is here?
},
contentType="application/pdf"
)
downloadButton(
outputId="downloadBtn",
label="Download Report"
)
},
onRejected=function(error){
showNotification(
error$message,
duration=NULL,
type="error"
)
HTML("")
}
)$finally(remove_modal_spinner)
})

})

}

shinyApp(ui = ui, server = server)

型
单击“Build Report”按钮确实生成了.pdf文件--使用`tempdir()`,我可以导航到会话的临时目录,看到.Rmd文件已经被绑定,.pdf文件就在那里,用通常的临时文件哈希命名,打开时看起来和预期的一样。然而,单击“Download Report”按钮并不提供. pdf文件。相反,我得到一个.html文件的对话框,它不包括`downloadHandler`中指定的文件名。打开它会产生一个.html窗口,看起来与原始的Shiny应用程序页面相似。
x1c 0d1x的数据
考虑到.pdf * 确实 * 生成了,我猜问题出在`downloadHandler(content)`的某个地方,但是我不太熟悉`chrome_print(async=TRUE)`如何与`library(promises)`、`$then()`和临时文件一起工作,以便将.pdf从Temp目录中拉出并将其插入处理程序。
uxhixvfz

uxhixvfz1#

output_file_path作为reactiveVal。这将作为生成的PDF的路径的存储点。此外,downloadHandler应该独立定义,使用output_file_path中保留的路径。
downloadHandler然后利用这个存储的路径来促进PDF文件的下载:注意无耻的自我推销(我在SO上问了一些关于这个主题的问题)。参见hereherehere。这些只是轻微相关的,因为我相信你的问题来自承诺(但我不确定):

library(pagedown)
library(promises)
library(rmarkdown)
library(shiny)
library(shinybusy)

chrome_extra_args <- function(default_args = c("--disable-gpu")) {
  args <- default_args
  # Test whether we are in a shinyapps container
  if (identical(Sys.getenv("R_CONFIG_ACTIVE"), "shinyapps")) {
    args <- c(args,
              "--no-sandbox", # required because we are in a container
              "--disable-dev-shm-usage") # in case of low available memory
  }
  args
}

# send the .Rmd to temp
tempReport <- tempfile(fileext=".Rmd")
file.copy("ReportGenerator.Rmd", tempReport, overwrite=TRUE)

# <- changed here
ui <- fluidPage(
  titlePanel("ABR Dashboard"),
  actionButton(inputId = "buildBtn", label = "Build Report"),
  uiOutput("downloadBtn")
)

server <- function(input, output) {
    
    # new a path for the pdf
    output_file_path <- reactiveVal()
    
    observeEvent(input$buildBtn, {
      show_modal_spinner()
      # generate PDF
      promise <- chrome_print(
        input = render(tempReport,
                       # will have params here later
                       envir = new.env(parent = globalenv())
        ),
        output = tempfile(fileext = ".pdf"),
        extra_args = chrome_extra_args(),
        verbose = 1,
        async = TRUE
      )
      
      promise$then(
        onFulfilled = function(value) {
          output_file_path(value) # <- store to path to the generated pdf
          remove_modal_spinner()
          showNotification("PDF file successfully generated", type = "message")
        },
        onRejected = function(error) {
          remove_modal_spinner()
          showNotification(error$message, duration = NULL, type = "error")
        }
      )
    })
    
    output$downloadBtn <- renderUI({
      if (!is.null(output_file_path())) {
        downloadButton(outputId = "downloadPDF", label = "Download Report")
      }
    })
    
    output$downloadPDF <- downloadHandler(
      filename = "Report.pdf",
      content = function(file) {
        file.copy(output_file_path(), file, overwrite = TRUE)
      },
      contentType = "application/pdf"
    )

}

shinyApp(ui = ui, server = server)

字符串

相关问题