displaying a pdf from a local drive in shiny

To embed a PDF viewer (the default PDF viewer of your web browser, pdf.js on mozilla for example) in your Shiny ui, you can use an iframe which the src will be the path to your PDF.

Here is 2 differents ways to include an iframe in your interface :

in the Ui you can directly add an iframe tag with an absolute src attribute as bellow :

tags$iframe(style="height:600px; width:100%", src="http://localhost/ressources/pdf/R-Intro.pdf"))

Or get an URL from the ui in the server , write the iframe tag with the input URL and return the HTML code in a htmlOutput in the ui :

Ui :
textInput("pdfurl", "PDF URL")
htmlOutput('pdfviewer')

Server :

output$pdfviewer <- renderText({
    return(paste('<iframe style="height:600px; width:100%" src="', input$pdfurl, '"></iframe>', sep = ""))
})

Note that when pages are loaded with a HTTP(S) protocol (the case of the Shiny app) for security reasons you can't framed locals files with their "file:" URLs. If you want to display locals pdf you should access to them with a http(s): URL, so you have to save them in your www directory (a local web server) and access to files with their http(s): URLs (the URL will be something like http://localhost/.../mypdf.pdf) as in the second iframe of my example. (Then you can't use a fileInput directly, you have to format it)

Ui.R :

library(shiny)

row <- function(...) {
  tags$div(class="row", ...)
}

col <- function(width, ...) {
  tags$div(class=paste0("span", width), ...)
}

shinyUI(bootstrapPage(

  headerPanel("PDF VIEWER"),

  mainPanel(

    tags$div(
      class = "container",

      row(
        col(3, textInput("pdfurl", "PDF URL"))
      ),
      row(
        col(6, htmlOutput('pdfviewer')),
        col(6, tags$iframe(style="height:600px; width:100%", src="http://localhost/ressources/pdf/R-Intro.pdf"))
      )
    )
  )
))

Server.R :

shinyServer(function(input, output, session) {

  output$pdfviewer <- renderText({
      return(paste('<iframe style="height:600px; width:100%" src="', input$pdfurl, '"></iframe>', sep = ""))
  })

})

The web pages with the PDF viewers :

enter image description here

Hope this help.


Create a folder called www in the original directory that contains your server.R and ui.R scripts. Place the PDF in the www/ folder, then use something like the code below:

In server.R:

shinyServer(function(input, output) {

  observeEvent(input$generate, {
    output$pdfview <- renderUI({
      tags$iframe(style="height:600px; width:100%", src="foo.pdf")
    })
  })
})

In ui.R:

shinyUI(fluidPage(

  titlePanel("Display a PDF"),

  sidebarLayout(
    sidebarPanel(
      actionButton("generate", "Generate PDF")
    ),

    mainPanel(
      uiOutput("pdfview")
    )
  )
))

Additional to Fabian N.'s answer.

There are two important things:

  1. Make sure you create a R Shiny Web Application from Rstudio. Make sure you run as "Run App". Otherwise, files in "www" folder can not be accessed!

enter image description here

  1. Make sure you create a "www" folder in Web Application directory.