0

I want to be able to use the name of a file uploaded to my shiny app in the download handler. My use case it to generate a report and concatenate the original file name (the one uploaded) with additional text.

I created a MWE app where you can upload a CSV file and download the same file. The downloaded file should have the same name with "NEW " prepended.

---
title: Test downloading file with correct name
runtime: shiny
output: 
  flexdashboard::flex_dashboard
---

# Sidebar {.sidebar}

```{r}

#############
## Upload  ##
#############
fileInput("file", "Upload CSV File",
          accept = c(
              "text/csv",
              "text/comma-separated-values,text/plain",
              ".csv"))

######################################
## Download file with the same name ##
######################################
downloadHandler(
    filename = paste("NEW", input$file$name),
    content = function(file) {
        write.csv(x = read.csv(input$file$datapath),
                   file = file, row.names = FALSE)
    },
    outputArgs = list(label = "Download Uploaded File"))

```

Instead, the downloaded file is named NEW_ but the contents are correct.

I found that I could get it to name the file correctly (at least sometimes) by adding an observe statement on the file name:

---
title: Test downloading file with correct name
runtime: shiny
output: 
  flexdashboard::flex_dashboard
---

# Sidebar {.sidebar}

```{r}

#############
## Upload  ##
#############
fileInput("file", "Upload CSV File",
          accept = c(
              "text/csv",
              "text/comma-separated-values,text/plain",
              ".csv"))

######################################
## Download file with the same name ##
######################################
downloadHandler(
    filename = paste("NEW", input$file$name),
    content = function(file) {
        write.csv(x = read.csv(input$file$datapath),
                   file = file, row.names = FALSE)
    },
    outputArgs = list(label = "Download Uploaded File"))

```
```{r, echo = FALSE}

## This doesn't produce output but is necessary to ensure that output files are
## named correctly
observe({
    show(input$file$name)
})

```

The help file for shiny::downloadHandler() says that reactive expressions can be used in the content function so why does the first code chunk not work?

Stefan Avey
  • 1,148
  • 12
  • 23

1 Answers1

0

I got it working by adding an event observer. I'm not sure if this works with your case, but it produced the desired outcome. I also made most comment directly in code

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = TRUE)
```
# Sidebar {.sidebar}

```{r echo=FALSE}

shinyApp(

  ui = fluidPage(
    fileInput("file", "Upload CSV File",
              accept = c(
                "text/csv",
                "text/comma-separated-values,text/plain",
                ".csv")),
    downloadButton("downloadData", label = "DL")
  ),

  server = function(input, output, session) {
    # Wait for input$file to change so we know there is data available
    observeEvent(input$file, {
      # store all the input$file objects on the_f
      the_f <- as.list(input$file)
      # Create the new file name for downloading
      new_name <- sprintf("NEW_%s.csv", the_f[['name']])
      # Go ahead and read in
      new_dat <- read.csv(the_f[['datapath']])
      # DL handler
      output$downloadData <- downloadHandler(
        filename = function(){
          # Just use the name from outside the handler we already created
          new_name
        },
          # Handle content as follows
        content = function(file){
          write.csv(new_dat, file = file, row.names = FALSE)
        }
      )
    })
  }
)
```

enter image description here

Carl Boneri
  • 2,632
  • 1
  • 13
  • 15
  • Thanks Carl. This may work for a Shiny app but I tried it in the context of `flexdashboard` with my example and it doesn't work to wrap the `downloadHandler()` in an `observeEvent(input$file...` call. The download button does not appear even after uploading a file. – Stefan Avey Sep 11 '18 at 20:52
  • yea.. sorry about that. I kind of realized after i answered.. that io didn't actually answer your question/problem. – Carl Boneri Sep 11 '18 at 22:19