15

I can't make shiny's downloadHandler to output the zip file:

# server.R
library(shiny)

shinyServer(function(input, output) {  
  output$downloadData <- downloadHandler(
    filename <- function() {
      paste("output", "zip", sep=".")
    },

    content <- function(fname) {
      fs <- c()
      tmpdir <- tempdir()
      setwd(tempdir())
      for (i in c(1,2,3,4,5)) {
        path <- paste0("sample_", i, ".csv")
        fs <- c(fs, path)
        write(i*2, path)
      }
      zip(zipfile=fname, files=fs)
    }
  )
})

And the simple ui.R:

shinyUI(fluidPage(
  titlePanel(""),
  sidebarLayout(
    sidebarPanel(
      downloadButton("downloadData", label = "Download")
    ),
    mainPanel(h6("Sample download", align = "center"))
  )
))

I'm having nice output, except the error:

> shiny::runApp('C:/Users/user/AppData/Local/Temp/test')

Listening on http://127.0.0.1:7280
  adding: sample_1.csv (stored 0%)
  adding: sample_2.csv (stored 0%)
  adding: sample_3.csv (stored 0%)
  adding: sample_4.csv (stored 0%)
  adding: sample_5.csv (stored 0%)
Error opening file: 2
Error reading: 6

And no save dialog to save the archive. But in the temp folder the right archive is presented. How to properly share the archive?

m0nhawk
  • 22,980
  • 9
  • 45
  • 73
  • Try the `library(Rcompression)` function `zip` to see whether it can help http://stackoverflow.com/questions/4624360/creating-zip-file-from-folders – Keniajin Nov 12 '14 at 08:05
  • Just the note, on Windows you need Rtools installed and its bin directory need to be in your PATH env, otherwise zip function will just silently do nothing. – jcubic Jun 14 '19 at 15:01

2 Answers2

16

You are using <- inside the downloadHandler function and should be using =. Also you may need to define the contentType:

library(shiny)

runApp(
  list(server = function(input, output) {  
    output$downloadData <- downloadHandler(
      filename = function() {
        paste("output", "zip", sep=".")
      },
      content = function(fname) {
        fs <- c()
        tmpdir <- tempdir()
        setwd(tempdir())
        for (i in c(1,2,3,4,5)) {
          path <- paste0("sample_", i, ".csv")
          fs <- c(fs, path)
          write(i*2, path)
        }
        zip(zipfile=fname, files=fs)
      },
      contentType = "application/zip"
    )
  }
  , ui = fluidPage(
    titlePanel(""),
    sidebarLayout(
      sidebarPanel(
        downloadButton("downloadData", label = "Download")
      ),
      mainPanel(h6("Sample download", align = "center"))
    )
  ))
)
jdharrison
  • 30,085
  • 4
  • 77
  • 89
  • 4
    I noticed, that the zip download does not work for me if I use the Rstudio Browser. So you might want to try it in an external browser to make sure. – jakob-r Nov 23 '16 at 15:42
  • I think that using `setwd` anywhere, especially in a Shiny app is quite dangerous. Use `zip(..., flags = "-j")` instead, that gets rid of the "junk path" and stores only the names of the files. – GyD Aug 31 '18 at 08:29
  • 2
    This program results in no download for me I get a download failed box at the bottom of my browser with the messafe "Failed - no file". Any idea what could be wrong? – Vishesh Shrivastav Sep 17 '18 at 18:59
  • Piggybacking on the comment from @jakob-r, the zip download *kind* of doesn't work in the Rstudio browser. It will default to an extension-less file, named "downloadData", which is the name of the download button, ignoring whatever name you provide. If you add the zip extension, either when saving, or by renaming the file, it works. In other browsers it works fine, though. – Anonymous coward Mar 20 '19 at 20:34
0

You could also compress your folder using tar:

output$files_tar_button <- downloadHandler(
    filename <- function() {
      paste("output", "tar", sep=".")
    },

    content <- function(file) {
      tar(file, "file/path/")
    }
  ) 
Nivel
  • 629
  • 4
  • 12