R语言 如何有一个动作按钮,自动下载一个csv文件(不是下载按钮?)

cx6n0qe3  于 2023-03-10  发布在  其他
关注(0)|答案(1)|浏览(192)

我有一个很棒的应用程序,用户可以在其中输入数据,然后点击操作按钮将数据提交到数据库中,我还有一个下载按钮,可以让用户以csv格式在本地下载数据的副本。
我现在要做的是当用户点击操作按钮时自动下载数据。我在网上找过了,但找不到太多的信息。任何帮助或想法都很感激。
我有一个小的应用程序代码如下.

library(shiny)
library(gt)

#------------------------------#
# GLOBAL
#------------------------------#
gt_tbl <-
  gtcars %>%
  gt() 

#------------------------------#
# UI
#------------------------------#
ui <- fluidPage(
  downloadButton('downloadData', 'Download data'),
  actionButton('button', "ACTOIN BUTTON"),
  gt_output(outputId = "table")
)

#------------------------------#
# SERVER
#------------------------------#
server <- function(input,output,session) {
  
  
  #ACTION BUTTON 
  observeEvent(input$button, {
    withProgress(message = "You clicked this button.... Working...", value =0 , {
    Sys.sleep(3)
    
    #INSERT FUNCTION HERE LIKE WRITING TO DB
    incProgress(.25,message = "Writing to database.... Working...")
    Sys.sleep(3)
    
    #AUTOMATICALLY DOWNLOAD BUTTON NEXT?
    incProgress(.35, message = "Saving a copy of data locally.... Working...")
    #output$downloadData
    
    Sys.sleep(3)
    incProgress(1, message = "COMPLETE!")
    Sys.sleep(3)
    })
  })
  
  # TABLE
  output$table <- render_gt(
    expr = gt_tbl
    )
  
  # TRADITIONAL DOWNLOAD BUTTON 
  output$downloadData <- downloadHandler(
    filename = function() { 
      paste("dataset-gtcars-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(gtcars, file)
    })

}

#------------------------------#
# RUN APP
#------------------------------#
shinyApp(ui=ui,server=server)
k5ifujac

k5ifujac1#

将找到的答案here与您的代码结合在一起,您可以执行以下操作:

library(shiny)
library(gt)
library(shinyjs)

#------------------------------#
# GLOBAL
#------------------------------#
gt_tbl <-
  gtcars %>%
  gt() 

# function which checks the data; returns TRUE or FALSE
checkData <- function(dat){
  TRUE
}

# function which transforms the data; returns NULL if check not TRUE
processData <- function(dat){
  if(checkData(dat)){
    # do something with dat
    names(dat) <- toupper(names(dat)) # for our example
    return(dat)
  }else{
    return(NULL)
  }
}

#------------------------------#
# UI
#------------------------------#
ui <- fluidPage(
  useShinyjs(),
  conditionalPanel(
    "false", # always hide the download button
    downloadButton("downloadData")
  ),
  actionButton("button", "Download"),
  gt_output(outputId = "table")
)

#------------------------------#
# SERVER
#------------------------------#
server <- function(input,output,session) {
  
  finalData <- reactiveVal() # to store the processed data
  
  #ACTION BUTTON 
  observeEvent(input$button, {
    withProgress(message = "You clicked this button.... Working...", value =0 , {
      Sys.sleep(3)
      
      #INSERT FUNCTION HERE LIKE WRITING TO DB
      incProgress(.25,message = "Writing to database.... Working...")
      Sys.sleep(3)
      
      # PROCESS DATA
      if(!is.null(df <- processData(gtcars))){
        finalData(df)
        runjs("$('#downloadData')[0].click();") # DOWNLOAD BUTTON
      }else{
        # something which throws an alert message "invalid data" 
        # (eg with shinyBS::createAlert or shinyWidgets::sendSweetAlert)
      }
      
      Sys.sleep(3)
      incProgress(1, message = "COMPLETE!")
      Sys.sleep(3)
    })
  })
  
  # TABLE
  output$table <- render_gt(
    expr = gt_tbl
  )
  
  # DOWNLOAD BUTTON 
  output$downloadData <- downloadHandler(
    filename = function() { 
      paste("dataset-gtcars-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(finalData(), file)
    })
  
}

#------------------------------#
# RUN APP
#------------------------------#
shinyApp(ui=ui,server=server)

该应用程序包含一个操作按钮,它模拟将数据写入数据库,然后将处理后的数据下载为CSV文件的过程。processData函数接受输入数据并对其进行转换(在本例中,它将列名更改为全大写;我在另一个示例答案中保持了这一点)。checkData函数总是返回TRUE,但是您可以自定义它以检查数据的有效性。
点击操作按钮时,会出现一个进度条,其中包含一条消息,指示应用程序正在运行。几秒钟的延迟后,系统会处理数据,并自动点击下载按钮(使用JavaScript)下载.csv文件。如果数据无效,它可能会使用shinyBS::createAlertshinyWidgets::sendSweetAlert等函数抛出警报消息(代码不包括此功能,我只是在另一个答案的相同注解中写入)。
解决方案主要是使用"false"作为条件的conditionalPanel,默认隐藏下载按钮,这样可以保证只有在用户点击动作按钮并且数据处理成功后,下载按钮才会出现。

相关问题