如何在使用 shiny 下载处理程序下载的 table 顶部插入一行文本?

How to insert a row of text on top of a table downloaded using the shiny download handler?

选择的解决方案添加到此 OP 的末尾

在下面缩短的可重现代码中,用户可以通过单击 UI 顶部的 downloadButton() 下载输出数据帧。下载为 csv 文件时,如何在 table 上方插入一行描述 table 的文本?如下图所示。

可重现代码:

library(dplyr)
library(DT)
library(shiny)
library(shinyWidgets)
library(tidyverse)

ui <-
  fluidPage(fluidRow(
    column(width = 8,
           h3("Click below to download:"),
           downloadButton("sumsDownload","Download",style = "width:20%;"),
           h3("Summed Data:"),
           DT::dataTableOutput("sums")
          )
  ))

server <- function(input, output, session) {
  data <- reactive({
    data.frame(
      Period = c("2020-01", "2020-02", "2020-03", "2020-01", "2020-02", "2020-03"),
      ColA = c(1000.01, 20, 30, 40, 50, 60),
      ColB = c(15.06, 25, 35, 45, 55, 65)
    )
  })
  
  summed_data <- reactive({
    data() %>%
      group_by(!!sym("Period")) %>%
      select("ColA", "ColB") %>% summarise(across(everything(), sum))
  })
  
  output$sums <- renderDT({datatable(data = summed_data(),rownames = FALSE)})
  
  output$sumsDownload <- downloadHandler(
    filename = function() {paste("sumsDownload","csv",sep=".")},
    content = function(file) {write.csv(summed_data(), file,row.names=FALSE)}
  )
  
}

shinyApp(ui, server)

选择的解决方案:

创建一个反应性数据框 df,将 summed_data() 数据框与一个向量(放置在 df 数据框的顶部)合并,table 名称为“ Summed Data" 后跟该行中的一系列 NA,然后在 downloadHandler() 中将其过滤掉。下面的 downloadHandler() 也是从 OP 修改而来,将 write.csv() 替换为 write.table()

df <- reactive({ # `df` modifies `summed_data` for csv download
    as.data.frame(
      rbind(
        c("Summed Data",rep(NA,ncol(summed_data())-1)),
        colnames(summed_data()),
        matrix(unlist(summed_data(), use.names=FALSE),
               nrow = nrow(summed_data()),
               )
          )
      )
  })
  
  output$sumsDownload <- downloadHandler(
    filename = function() {paste("sumsDownload","csv",sep=".")},
    content = function(file){
      write.table( 
        df(),
        na = "", 
        file, 
        sep = ",", # add this per road_to_quantdom on May/05/22
        col.names = FALSE, 
        row.names = FALSE)
      }
  )
}

以附加模式打开输出文件,写入header行,然后写入 CSV 数据:

f <- file("mtcars.csv", "a")
writeLines("Motor Trend Car Road Tests", f)
write.csv(mtcars, f)
close(f)

head(readLines("mtcars.csv"))
#> [1] "Motor Trend Car Road Tests"                                                                   
#> [2] "\"\",\"mpg\",\"cyl\",\"disp\",\"hp\",\"drat\",\"wt\",\"qsec\",\"vs\",\"am\",\"gear\",\"carb\""
#> [3] "\"Mazda RX4\",21,6,160,110,3.9,2.62,16.46,0,1,4,4"                                            
#> [4] "\"Mazda RX4 Wag\",21,6,160,110,3.9,2.875,17.02,0,1,4,4"                                       
#> [5] "\"Datsun 710\",22.8,4,108,93,3.85,2.32,18.61,1,1,4,1"                                         
#> [6] "\"Hornet 4 Drive\",21.4,6,258,110,3.08,3.215,19.44,1,0,3,1"