關于 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)
我有一些存盤在reactiveValues串列中的資料集,我希望用戶能夠下載它們。理想情況下,我希望他們能夠一次下載多個檔案,而不zip必先下載它們,然后再下載一個.zip檔案。我可以接受的另一個選擇是將每個資料集添加到 Excel 作業表中,然后下載多作業表 Excel 檔案。我的一般思考程序(關于前者)如下:
- 下載按鈕被按下
- 創建一些臨時目錄
- 將
NULL包含在to_downloadreactiveValues 串列中的(非)資料集寫入此目錄 zip臨時目錄和下載
我覺得我很接近,但是我還沒有能夠成功地得到這個作業。有任何想法嗎?
編輯 1:我知道這里建議的答案,但我想避免使用,setwd()因為我認為在 Shiny 應用程式中弄亂作業目錄是不好的做法。
uj5u.com熱心網友回復:
編輯了一些內容并且它正在作業:
- 在呼叫中使用
dir而不是顯示臨時目錄的內容(列出 R 環境而不是目錄內容)lszip::zipls - 作為進一步的建議:在里面創建一個新的、唯一的檔案夾
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)
在我自己的 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"
)
...
由reprex 包(v2.0.1)于 2021 年 12 月 16 日創建
轉載請註明出處,本文鏈接:https://www.uj5u.com/net/383096.html
