AwaitedOne
AwaitedOne

Reputation: 1012

How to download a PDF file in a Shiny app

I have one PDF in the www directory of my shiny app. I would like that file to be available for download. How can i do that.

The download example works well, but no idea to use it for PDF download from www directory.

## Only run examples in interactive R sessions
if (interactive()) {

ui <- fluidPage(
  downloadLink("downloadData", "Download")
)

server <- function(input, output) {
  # Our dataset
  data <- mtcars

  output$downloadData <- downloadHandler(
    filename = function() {
      paste("data-", Sys.Date(), ".csv", sep="")
    },
    content = function(file) {
      write.csv(data, file)
    }
  )
}

shinyApp(ui, server)
}

Upvotes: 15

Views: 17526

Answers (3)

Roger
Roger

Reputation: 452

(Adding again in "Your Answer"... to use the formatting.) @Bill34 gave me the answer I need. This post extends the idea.

My app helps the user to create certain files of interest. Then I use my package shinyDebuggingPanel (on github), open up an interactive R box with control-D, and paste in:

system('cp file-to-download www') 
tags$a("Click here to get the file", href="file-to-download") 

click and !voila! here it is: file-to-download is in your local Downloads folder.

PS: I use shinyDebuggingPanel a LOT. Forgot to make the www folder? No problem! Control-D to open shinyDebuggingPanel, and paste in system('mkdir www')

Upvotes: 0

Billy34
Billy34

Reputation: 2214

If the file is in the www folder then you simply have to provide a link to it in the UI

... (in UI)
  tags$a("Click here to get the PDF", href="your-pdf-name.pdf")
...

If the filename is not known at start time then use uiOutput/renderUI and set rv$filename to the filename when you generate it.

... (in UI)
  uiOutput("dlURL")
...


... (in server)
  rv <- reactiveValues(filename="")

  output$dlURL <- renderUI({
    tags$a("Click here to get the file", href=rv$filename)
  })
...

Upvotes: 3

Tom&#225;s Barcellos
Tom&#225;s Barcellos

Reputation: 824

Take a look in the downloadHandler function documentation, it has two arguments without default values: filename and content.

filename is basically the name of the file that will be downloaded. It has not to be inside a function. filename = "your-pdf-name.pdf" works as much as defining it inside the argumentless function.

content, in the other hand, creates a tempfile with the content that is going to be downloaded. In most cases you're going to create a file that is going to be fulfilled with something you have created in you app.

How that is not your case, my solution provides something we call "gambiarra" in Brasil: it copies the file you want to download to the tempfile that shiny needs to the downloadHandler works. (I've tried just define it as the path to the file but it doesn't work)

ui <- fluidPage(
  downloadLink("downloadData", "Download")
)

server <- function(input, output) {

  output$downloadData <- downloadHandler(
    filename = "your-pdf-name.pdf",
    content = function(file) {
      file.copy("www/teste.pdf", file)
    }
  )
}

shinyApp(ui, server)

Upvotes: 21

Related Questions