Download Multiple CSV Files with One Button (Downloadhandler) with R Shiny

How to download multiple files from R/Shiny app?

A few things edited and it's working:

  • using dir instead of ls inside the zip::zip call to show the contents of the temp directory (ls lists R environment rather than directory contents)
  • as a further suggestion: making a new, unique folder inside tempdir() to ensure only relevant files are added.
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)

In my own Shiny app I had used a multi-worksheet approach as you suggested above. An alternative setup which works to produce a multi-sheet xlsx workbook using openxlsx could be:

...

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"

)

...

Created on 2021-12-16 by the reprex package (v2.0.1)

Download multiple checkboxes in a single csv file via downloadhandler- R Shiny

Is this what you're looking for?

library(shiny)

c_antel <- data.frame(cn = c("Urinary tract infections this pregnancy",
"Urinary tract infections this pregnancy, treated",
"Anemia this pregnancy (HCT < 30/Hgb <10)",
"Hemoglobinopathy this pregnancy",
"Coagulation disorder",
"Rh sensitization",
"Other iso-immunization",
"Biliary/liver disorder(Yes at delivery)",
"Cardiac disease",
"Autoimmune disease",
"Antiphospholipid syndrome",
"Specify collagen vascular disease",
"Asthma",
"Acute or chronic lung disease",
"Renal disorder/disease",
"Renal dialysis or end stage renal disease",
"Thyroid disease",
"Cancer this pregnancy",
"Cancer treatment this pregnancy"),
cv = c("RFC_INFUT",
"RFC_INFUTTX",
"RFC_ANEMIA",
"RFC_HEMO",
"COAGULATION_DISORDER",
"RFC_RHS",
"RFC_ISO",
"BILARY_LIVE_DISORD",
"RFC_CDDZ",
"RFC_CVDZ",
"RFC_APSY",
"RFC_CVSPEC",
"RFC_ASTH",
"RFC_LGDZ",
"RENAL_DISORDER_DISEASE",
"RFC_RNDY",
"RFC_THYDZ",
"RFC_CA",
"CANCER_TREATMENT"))

c_fetal <- data.frame(cn = c("Decreased fetal movement",
"Abnormal fetal heart rate/rhythm",
"Suspected IUGR this pregnancy",
"Fetal compromise this pregnancy",
"Suspected Fetal CNS Anomaly",
"Diagnosed fetal anomaly:",
"Fetal damage",
"Postterm, > 41 6/7 weeks"),
cv = c("RFC_FETMOV",
"RFC_ABRHY","RFC_IUGR",
"RFC_FCOMP",
"RFC_FEANOM",
"RFC_FAN",
"RFC_FD",
"RFC_POST"))

c_mater <- data.frame(cn = c("Maternal traumatic injury during this pregnancy",
"Domestic violence during this pregnancy",
"aternal surgical procedure during this pregnancy",
"Other antenatal risk factors during this pregnancy:_____"),
cv = c("RFC_TINJ",
"RFC_VIOL",
"RFC_SURG",
"RFC_OTHR"))
ui <- fluidPage(
titlePanel(h1(" Worksheet",align="center")),
hr(),

sidebarPanel(
titlePanel(h4("Antenatal Risk Factors/Current Pregnancy",align="center")),
hr(),
checkboxGroupInput("Antel", " ",
choiceNames = c_antel$cn,
choiceValues = c_antel$cv
),
checkboxGroupInput("Fetal", "Fetal Conditions",
choiceNames = c_fetal$cn,
choiceValues = c_fetal$cv
),
checkboxGroupInput("Maternal", "Maternal Characteristics",
choiceNames = c_mater$cn,
choiceValues = c_mater$cv
)
),
downloadButton("download_checkboxes", "download"),
#______________END_______________#
)

server <- function(input, output) {

output$download_checkboxes <- downloadHandler(
contentType = "text/csv",
filename = "results.csv",
content = function(file) {
Data <- data.frame(
key = c(input$Antel,
input$Fetal,
input$Maternal),
value = c(c_antel$cn[c_antel$cv %in% input$Antel],
c_fetal$cn[c_fetal$cv %in% input$Fetal],
c_mater$cn[c_mater$cv %in% input$Maternal])
)
write.csv(Data, file, row.names = F)
}
)

}

shinyApp(ui = ui, server = server)

R shiny: download multiple .csv files

You forgot to put quotes"" in the qmethod argument. Your download handler for classify should be this:

output$download_classify <- downloadHandler(
filename = function() {
paste0("rating", ".csv")
},
content = function(file) {
write.table(
result()$rating,
file,
sep = ";",
col.names = NA,
qmethod = "double"
)
}
)

shiny: download multiple local files from server

You could store the result data files on an http accessable folder on the shiny server, and supply a simple download link to that file in your shiny app.

Saving multiple data-frames to single csv file using Shiny downloadHandler

Other options:

  1. Write an Excel workbook with one sheet per
    dataframe
  2. Zip together multiple csv
    files

Here's a sample of both options using four dataframes from the R Datasets Package.

library(shiny)
library(xlsx)

shinyApp(
ui = fluidPage(
downloadButton("downloadExcelSheet", "Download Excel Workbook with Multiple Sheets"),
downloadButton("downloadZippedCSV", "Download zipped csv files")
),
server = function(input, output) {

#### Write an Excel workbook with one sheet per dataframe ####
output$downloadExcelSheet <- downloadHandler(
filename = function() {
"excelWorkbook.xlsx"
},
content = function(file) {
# write workbook and first sheet
write.xlsx(mtcars, file, sheetName = "mtcars", append = FALSE)

# add other sheets for each dataframe
listOtherFiles <- list(iris = iris,
airquality = airquality,
sleep = sleep)
for(i in 1:length(listOtherFiles)) {
write.xlsx(listOtherFiles[i], file,
sheetName = names(listOtherFiles)[i], append = TRUE)
}
}
)

#### Zip together multiple csv files ####
output$downloadZippedCSV <- downloadHandler(
filename = function() {
"zippedCSV.zip"
},
content = function(file) {
# go to temp dir to avoid permission issues
owd <- setwd(tempdir())
on.exit(setwd(owd))

# create list of dataframes and NULL value to store fileNames
listDataFrames <- list(mtcars = mtcars,
iris = iris,
airquality = airquality,
sleep = sleep)
allFileNames <- NULL

# loop through each dataframe
for(i in 1:length(listDataFrames)) {
# write each dataframe as csv and save fileName
fileName <- paste0(names(listDataFrames)[i], ".csv")
write.csv(listDataFrames[1], fileName)
allFileNames <- c(fileName, allFileNames)
}

# write the zip file
zip(file, allFileNames)

}
)
}
)

Download multiple csv files in a zipped folder in Shiny

The top solution still wasn't working for me. I was working in RStudio Server on a Linux server. The problem was that RStudio couldn't automatically locate the path to the zip executable. I had to manually specify it. In the command line, which zip revealed to me /usr/bin/zip.

So, I just had to set the R_ZIPCMD environment variable at the top of my code.

Sys.setenv(R_ZIPCMD="/usr/bin/zip")

Source: The help file for zip() mentions R_ZIPCMD.



Related Topics



Leave a reply



Submit