基于文件路径的闪亮下载文件

时间:2016-09-23 14:16:31

标签: r shiny

我有一个文件,我生成闪亮 用户单击一个按钮,文件应该下载。然而,没有任何事情发生

函数export_report生成excel文件并将其保存到某个位置。然后,该函数将文件位置传递回下载处理程序,以便下载该文件。问题似乎是它没有正确返回。我已经测试了闪亮之外的函数(export_report)并且它完美地返回了所有内容,所以我从闪亮的角度来看显然做错了。

文件本身是在应该在服务器上的地方创建的,因为我可以在RStudio中下载它并在文件资源管理器中查看它。任何人都可以帮忙

# 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)
  }
)

我见过其他例子R Shiny: Download existing file,这是我的代码基于

编辑1:添加带有一些假数据的export_report函数来运行它

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

}

要调用该功能,您可以使用以下数据

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

编辑2 我现在设法从中获取错误。当我在代码的cat(myfile)部分中filename = function() {时,在返回正确的文件路径后出现错误

  

rep中的警告(是,length.out = length(ans)):     'x'为NULL,因此结果为NULL   警告:ifelse出错:replacement的长度为零   堆栈跟踪(最里面的第一个):       1:runApp   错误:替换的长度为零

此错误主要是因为我的文件路径未传递到段myfile所以

如果有人可以告诉我如何将我的函数生成的文件路径发送到下面代码的服务器部分,这应该可以解决我的问题

content = function(file) {
    file.copy(myfile, file)
  }

3 个答案:

答案 0 :(得分:5)

感谢所有评论和澄清下载处理程序工作方式的人。 最后,我创建了一个新功能,将上面的导出功能分开 我使用的新函数名为generate_file(),只返回文件名

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

}

然后在服务器端

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)

  }
)

然后找到新创建的文件并将其导出给用户

答案 1 :(得分:3)

我刚刚使用此示例代码检查了您的问题并且它有效:

output$downloadData <- downloadHandler(
    filename = function() {
        data <- mtcars
        myfile <- "data.csv"
        write.csv(data, myfile)
        myfile
    },
    content = function(file) {
        print(file) //prints: [...]\\Local\\Temp\\RtmpEBYDXT\\fileab8c003878.csv
        file.copy(file, file)
    }
)

myfile 是下载文件的文件名。您不能在 file.copy 中将其用作输入,此变量超出范围。似乎R创建了一个临时文件名(参见print())。

答案 2 :(得分:1)

尝试使用filename函数定义路径或自定义文件名,以及内容部分中的write.csv。示例代码:

 output$downloadData <- downloadHandler(
    filename = function() {
        paste(<user_name or date for eg>, ".csv", sep="")
        },
    content = function(file) {
        write.csv(data, file)
    }    
 )

我在上面的评论中注意到,您已经询问过应用程序在多个用户使用时如何生成正确的文件。对于此部分,您需要使用session

因此,如果您的业务逻辑函数来自名为foo.R的R文件,则服务器代码应如下所示:

shinyServer(func = function(input, output, session) {
     source("./foo.R", local=TRUE)
     ......

这将为每个用户分离会话,从而在下载时生成特定于每个用户的文件。希望这能给你一些指示。