R Shiny中DT Buttons扩展下载文件名动态命名问题
这个问题我之前也碰到过,DT的Buttons扩展默认会把filename参数的值在初始化时固定下来,哪怕input$sample后续变化,按钮的下载文件名也不会跟着更新——因为按钮的配置是在表格第一次渲染时生成的,不会自动响应input的变化。下面给你两种可行的解决方案:
方法1:让DT的Buttons配置响应式更新
其实可以通过确保每次input$sample变化时,整个renderDataTable重新生成按钮配置来解决。你需要把按钮的filename直接放在renderDataTable的options里,利用Shiny的响应式特性,每次input变化时重新计算文件名:
library(shiny) library(DT) ui <- fluidPage( h2("Explorer"), tabPanel(h3("Inspector"), p("Overview of data for a particular sample."), selectInput(inputId = "sample", label = h3("Select sample"), selectize = TRUE, choices = names(vcf_tibbles)), dataTableOutput("sample_inspector") ) ) server <- function(input, output) { output$sample_inspector <- DT::renderDataTable( sample_overview(sample_id = input$sample, vcf_tibbles = vcf_tibbles), rownames = FALSE, extensions = 'Buttons', options = list( paging = FALSE, dom = 'Bfrtip', buttons = list( list( extend = 'csv', filename = paste0("snp-", input$sample) # 每次渲染都会重新计算文件名 ), list( extend = 'excel', filename = paste0("snp-", input$sample) ) ) ) ) }
如果之前这么写没生效,可能是因为sample_overview函数的响应式触发有问题?你可以检查一下vcf_tibbles是不是reactive对象,如果是的话,要确保它的依赖正确传递。不过如果你的表格内容已经能正常更新,那这个写法应该能让文件名跟着input$sample变化。
方法2:用Shiny原生下载按钮(更可控)
如果方法1还是有问题,推荐用Shiny自带的downloadHandler,自己添加下载按钮,这样完全掌控文件名和下载内容,稳定性更高:
修改UI部分:
ui <- fluidPage( h2("Explorer"), tabPanel(h3("Inspector"), p("Overview of data for a particular sample."), selectInput(inputId = "sample", label = h3("Select sample"), selectize = TRUE, choices = names(vcf_tibbles)), # 添加两个原生下载按钮 fluidRow( column(4, downloadButton("download_csv", "Download CSV")), column(4, downloadButton("download_excel", "Download Excel")) ), dataTableOutput("sample_inspector") ) )
修改Server部分:
server <- function(input, output) { # 先创建reactive对象存储当前选中样本的数据 current_sample_data <- reactive({ sample_overview(sample_id = input$sample, vcf_tibbles = vcf_tibbles) }) # 渲染表格 output$sample_inspector <- DT::renderDataTable( current_sample_data(), rownames = FALSE, options = list(paging = FALSE) ) # CSV下载处理 output$download_csv <- downloadHandler( filename = function() { paste0("snp-", input$sample, ".csv") }, content = function(file) { write.csv(current_sample_data(), file, row.names = FALSE) } ) # Excel下载处理(需要用到writexl或者openxlsx包) output$download_excel <- downloadHandler( filename = function() { paste0("snp-", input$sample, ".xlsx") }, content = function(file) { # 需先安装writexl包:install.packages("writexl") writexl::write_xlsx(current_sample_data(), file) } ) }
这种方法的好处是,文件名完全由downloadHandler的filename函数控制,每次点击按钮时都会重新获取当前的input$sample值,绝对不会出现文件名不更新的问题,而且你还能自定义按钮的样式和位置。
内容的提问来源于stack exchange,提问作者Yannick Wurm
相关产品推荐
相关产品推荐

