`downloadHandler`:下载失败(无数据)时如何优雅退出?

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

我有一个downloadButtondownloadHandler,当我们要下载数据,我必须运行一个程序,以找出是否有数据下载。
我无法找到一种方法来取消下载处理程序,下面的应用程序提示我们保存一些垃圾HTML文件。
如何让downloadHandler干净地退出?

library(shiny)

ui <- fluidPage(

  downloadButton("btn", "Download")
)

server <- function(input, output, session) {

  output$btn <- downloadHandler(
    filename = function(){
      "out.txt"
    },
    content = function(file){

# this example always fails.
      if(TRUE){
        print("Sorry, data not written.")
        return(NULL)
      } else {
        writeLines(mtcars, "out.txt")
      }

    }

  )

}

shinyApp(ui, server)
ar7v8xwq

ar7v8xwq1#

AFAIK,一旦按下按钮,就不可能取消下载。
下面是一种不使用downloadHandler下载文件的方法。它包括创建一个a元素,一旦你按下一个按钮,你想要下载的文件将被转换为base64编码,在shinyjs::runjs的帮助下,base64字符串将被赋予a元素的href属性,并触发对a元素的点击。

library(shiny)
library(shinyjs)

ui <- fluidPage(
  useShinyjs(),
  checkboxInput("data", "Data"),
  actionButton("btn", "Download"),
  tags$a(id = "dwnld")
)

server <- function(input, output, session) {

  observeEvent(input$btn, {
    if(input$data){
      tmpFile <- tempfile()
      write.table(iris, tmpFile)
      b64 <- base64enc::dataURI(file=tmpFile, mime="text/plain")
      runjs(sprintf('$("#dwnld").attr("href", "%s").attr("download", "out.txt")', b64))
      runjs("$('#dwnld')[0].click();")
    }else{
      runjs("alert('No data!');")
    }
  })

}

shinyApp(ui, server)
lymnna71

lymnna712#

我想有类似的东西,但在一个模块。诀窍是有一个隐藏的downloadbutton,使用JS(使用shinyjs)点击。
使用模块实现此功能的MWE如下所示

library(shiny)

download_ui <- function(id) {
  ns <- NS(id)
  tagList(
    shinyjs::useShinyjs(),
    actionButton(ns("download"), "Download"),
    div(downloadButton(ns("actual_download"), ""), style = "visibility: hidden") # hide this
  )
}

download_server <- function(id) {
  moduleServer(
    id,
    function(input, output, session) {
      
      observeEvent(input$download, {
        print("Performing some checks...")
        check <- TRUE
        
        if (!check) {
          showNotification("Abort Download", type = "error")
        } else {
          showNotification("Start Download", type = "message")
          
          shinyjs::runjs(paste0("document.getElementById('",
                                session$ns("actual_download"), "').click();"))
        }
        
        print("Done Download")
      })
      
      output$actual_download <- downloadHandler(
        filename = function() "test-file.csv",
        content = function(file) {
          print("Actually downloading the file")
          write.csv(mtcars[1:4, 1:5], file)
        }
      )
    }
  )
}

# Include the module in the main ui/server components
ui <- fluidPage(
  download_ui("down")
)
server <- function(input, output, session) {
  download_server("down")
}

shinyApp(ui, server)

相关问题