SO 上有许多关于此主题的不同问答,但我找不到适合我的用例的问答。我也感到非常惊讶的是,RStudio / Shiny 开发人员自己还没有拿出一些关于如何做到这一点的文档。无论如何,请看这个示例应用程序:
library(shiny)
library(glue)
library(tidyverse)
# Define UI for application
ui <- fluidPage(
# Application title
titlePanel("Test Multi-File Download"),
p("I hope this works!"),
downloadButton(
outputId = "download_btn",
label = "Download",
icon = icon("file-download")
)
)
# Define server logic
server <- function(input, output) {
#datasets stored in reactiveValues list
to_download <- reactiveValues(dataset1 = iris, dataset2 = airquality, dataset3 = mtcars, dataset4 = NULL)
blahblah <- iris
output$download_btn <- downloadHandler(
filename = function(){
paste("my_data_", Sys.Date(), ".csv", sep = "")
},
content = function(file){
#works
#readr::write_csv(blahblah, file)
#Attempt 1
# #create some temp directory
# temp_directory <- tempdir()
# browser()
# reactiveValuesToList(to_download) %>%
# #x is data, y is name
# imap(function(x,y){
# #browser()
# #check if data is not null
# if(!is.null(x)){
# #create file name based on name of dataset
# file_name <- glue("{y}_data.csv")
# #write file to temp directory
# readr::write_csv(x, file_name)
# }
# })
# zip::zip(
# zipfile = file,
# files = ls(temp_directory),
# root = temp_directory
# )
}
)
}
# Run the application
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)
我有一些数据集存储在reactiveValues列表中,我希望用户能够下载所有数据集。理想情况下,我希望他们能够一次下载多个文件,而不是必须先zip下载它们,然后再下载一个.zip文件。我可以接受的另一个选择是将每个数据集添加到 Excel 工作表中,然后下载多工作表 Excel 文件。我的总体思维过程(前者)如下:
NULL)数据集写入此目录to_downloadzip临时目录并下载我觉得我已经非常接近了,但是我还没有能够成功地完成这项工作。有任何想法吗?
编辑1:我知道这里建议的答案,但想避免使用,setwd()因为我认为在闪亮的应用程序中弄乱工作目录是不好的做法。
编辑了一些东西并且它正在工作:
dir而不是在调用ls内部zip::zip显示临时目录的内容(ls列出 R 环境而不是目录内容)tempdir(),以确保仅添加相关文件。library(shiny)
library(glue)
library(tidyverse)
# Define UI for application
ui <- fluidPage(
# Application title
titlePanel("Test Multi-File Download"),
p("I hope this works!"),
downloadButton(
outputId = "download_btn",
label = "Download",
icon = icon("file-download")
)
)
# Define server logic
server <- function(input, output) {
#datasets stored in reactiveValues list
to_download <- reactiveValues(dataset1 = iris, dataset2 = airquality, dataset3 = mtcars, dataset4 = NULL)
blahblah <- iris
output$download_btn <- downloadHandler(
filename = function(){
paste("my_data_", Sys.Date(), ".zip", sep = "")
},
content = function(file){
temp_directory <- file.path(tempdir(), as.integer(Sys.time()))
dir.create(temp_directory)
reactiveValuesToList(to_download) %>%
imap(function(x,y){
if(!is.null(x)){
file_name <- glue("{y}_data.csv")
readr::write_csv(x, file.path(temp_directory, file_name))
}
})
zip::zip(
zipfile = file,
files = dir(temp_directory),
root = temp_directory
)
},
contentType = "application/zip"
)
}
shinyApp(ui = ui, server = server)
Run Code Online (Sandbox Code Playgroud)
在我自己的 Shiny 应用程序中,我使用了您上面建议的多工作表方法。用于生成多页 xlsx 工作簿的替代设置openxlsx可能是:
...
output$download_btn <- downloadHandler(
filename = function(){
paste("my_data_", Sys.Date(), ".xlsx", sep = "")
},
content = function(file){
wb <- createWorkbook()
reactiveValuesToList(to_download) %>%
imap(function(x,y){
if(!is.null(x)){
addWorksheet(wb, sheetName = y)
writeData(wb, x, sheet = y)
}
})
saveWorkbook(wb, file = file)
},
contentType = "file/xlsx"
)
...
Run Code Online (Sandbox Code Playgroud)
由reprex 包于 2021 年 12 月 16 日创建(v2.0.1)