Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Shiny Download File based on File Path

Tags:

r

shiny

I have a file which i generate in shiny The user clicks a button and the file should download. However nothing happens

The function export_report generates the excel file and saves it to a location. The function then passes back the file location to the download handler so it will download the file. The problem seems to be that it isnt being returned correctly. I have tested the function (export_report) outside of shiny and it returns everything perfectly so I'm clearly doing something wrong from the shiny perspective.

The file itself is created where it is supposed to be on the server because i can download it within RStudio and see it in the file explorer. Can anyone help

# UI Section
downloadButton("downloadRpt", "Download Report")

# Server Section
output$downloadRpt <- downloadHandler(

  filename = function() {
    mydf <- report()
    dateRange <- input$dates_report
    selection <- input$selection 
    myfile <- export_report (mydf, selection, dateRange)
  },
  content = function(file) {
    file.copy(myfile, file)
  }
)

I have seen other examples R Shiny: Download existing file which is what my code is based on

EDIT 1: Adding the export_report function with some fake data to run it

export_report <- function(mydf,selection,dateRange) {

  # Template for where the template excel file is stored

  myoutputTemplate <- '/home/shiny_tutorials/Save to Database/templates/output_template.xlsx' 


  start_date <- dateRange[1] 
  end_date <- dateRange[2]
  date_range <- paste(start_date ,end_date, sep = " - " )

  # Load workbook the template workbook
  wb <- loadWorkbook(myoutputTemplate)

  # write to the workbook the data frame
  writeWorksheet(wb, mydf, sheet="Details",   
             startRow=8, startCol=2,    
             header=FALSE)                

  # add the the customer the user selected
  writeWorksheet(wb, selection, sheet="Details",   
             startRow=3, startCol=3,    
             header=FALSE)   

  # date
  writeWorksheet(wb, date_range, sheet="Details",   
             startRow=5, startCol=3,    
             header=FALSE)   

  # Create The file Name
  filename <- paste(selection, Sys.Date(), sep = " - ") %>% 
    paste(.,"xlsx", sep = ".")

  # removes the % sign and extra qoutes 
  filename <- gsub (pattern = '\'|%','', x = filename)

  # output directory
  myoutput <-  paste('/home/shiny_tutorials/Save to Database/output/',
               filename, sep = '')

  # Save workbook
  saveWorkbook(wb, myoutput)

  # Return File Path
  myoutput

}

To call the function you can use the data below

dateRange <- c("2011-09-23","2016-09-23")
selection = "COMPANY_A"
mydf <- iris
myfile <- export_report(mydf,selection,dateRange)

EDIT 2 I have now managed to get an error out of it. When i cat(myfile) in the filename = function() { section of the code i get the error after the correct file path has been returned

Warning in rep(yes, length.out = length(ans)) : 'x' is NULL so the result will be NULL Warning: Error in ifelse: replacement has length zero Stack trace (innermost first): 1: runApp Error : replacement has length zero

This error is basically because my file path does not get passed to the segment myfile so

if someone can tell me how to get the filepath generated by my function to the server section of the code below, that should fix my problem

content = function(file) {
    file.copy(myfile, file)
  }
like image 934
John Smith Avatar asked Jan 06 '23 07:01

John Smith


1 Answers

Thank you to everyone who commented and clarified my thinking a bit on how the download handler works. In the end, i created a new function which split up the export function above The new function i used is called generate_file() which simply returns the file name

generate_file_name <- function(selection) {

  # Create The file Name
  filename <- paste(selection, Sys.Date(), sep = " - ") %>% 
    paste(.,"xlsx", sep = ".")

  # removes the % sign and extra qoutes 
  filename <- gsub (pattern = '\'|%','', x = filename)

  # output directory
  myoutput <-  paste('/home/shiny_tutorials/Save to Database/output/',
                 filename, sep = '')

  # Return File Path
  myoutput

}

Then in the server side

output$downloadRpt <- downloadHandler(
  filename = function() {
    selection <- input$company
    generate_file_name(selection)
  },

  content = function(file) {

    mydf <- report()
    dateRange <- input$dates_report
    selection <- input$company
    export_report(mydf,selection,dateRange)
    myfile <- generate_file_name(selection)
    file.copy(myfile, file)

  }
)

This then finds the newly created file and exports it for the user

like image 107
John Smith Avatar answered Jan 13 '23 08:01

John Smith