Reputation: 49
I'm working on a Shiny app, in which the user uploads a file, which is then processed to generate a report, which the user can download as an editable Word .doc.
It works as intended, other than that although a "Save As" dialogue window appears which seems to allow you to choose the destination directory, the resulting .doc file ends up being saved to a temporary directory with a randomly-generated name (this is under Windows).
I suspect this is due to the use of the tempdir command, which is part of using rmarkdown to generate the downloaded file.
How should the below code be amended to allow the destination folder to be chosen?
#
# This is a Shiny web application. You can run the application by clicking
# the 'Run App' button above.
#
# Find out more about building applications with Shiny here:
#
# http://shiny.rstudio.com/
#
library(shiny)
library(knitr)
# Define UI for application that draws a histogram
ui <- fluidPage(
uiOutput('markdown'),
# Application title
titlePanel("Apptitle"),
# Sidebar with file input
sidebarLayout(
sidebarPanel(
fileInput(
inputId = "file1",
label = "Select file(s)",
multiple = TRUE,
accept = NULL,
width = NULL,
buttonLabel = "Browse...",
placeholder = "No file(s) selected"
),
downloadButton("report", "Generate report")
),
)
)
server <- function(input, output) {
output$report <- downloadHandler(
reactive(file <- input$file1),
filename = "wordreport.doc",
content = function(file) {
tempReport <- file.path(tempdir(), "wordreport.Rmd")
file.copy("wordreport.Rmd", tempReport, overwrite = TRUE)
params <- list(report.data = input$file1)
rmarkdown::render(tempReport, output_file = "wordreport.doc",
params = params,
envir = new.env(parent = globalenv()))
})
}
shinyApp(ui = ui, server = server)
Thank you for your help!
EDIT: Fixed, using the solution below, and the code edits suggested here: Passing a dataframe as a parameter from Shiny app to RMarkdown
Upvotes: 2
Views: 2044
Reputation: 11908
You're passing reactive(file <- input$file1)
as the contentType
argument to downloadHandler()
, which can't be good. Also, you're not writing anything to the file
given as an argument to the content
function.
Remove the reactive(file <- input$file1)
line, and specify output_file = file
in rmarkdown::render()
, and your download should work.
As discussed in the comments, you won't be able to have control over the download path though -- that's something the user's web browser and their settings there will decide.
Here's a somewhat more minimal app with a functioning file download, for reference:
library(shiny)
ui <- fluidPage(
sliderInput("value", "Some value", 1, 5, 2),
downloadButton("report", "Generate report")
)
server <- function(input, output) {
output$report <- downloadHandler(
filename = "wordreport.doc",
content = function(file) {
params <- list(value = input$value)
rmarkdown::render(
system.file("examples/knitr-minimal.Rmd", package = "knitr"),
output_file = file,
params = params,
envir = new.env(parent = globalenv())
)
}
)
}
shinyApp(ui, server)
Upvotes: 2