displaying a pdf from a local drive in shiny
Asked Answered
A

3

30

I'm still new to r and shiny, and i'm stumped with what should otherwise be simple logic. I am trying to display pdf files in imageOutput widgets but with no luck. Could someone steer me in the right direction?

sample ui.R

shinyUI(pageWithSidebar(
mainPanel(
  selectInput("sel_ed",
              label = "View outputs for Ecodistrict:", 
              choices = c(244,245,247,249), 
              selected = NULL,
              multiple = FALSE),

  imageOutput("imp_pdf",width="500px",height="500px")
))

sample server.R

shinyServer(function(input, output, session) {

importance <- function(inputSpecies){
img_dir <- pdf(paste(inputSpecies,"\\models\\MATL\\MATRF_Importance",sep=""))
}

output$imp_pdf <- renderImage({importance(input$sel_ed)}) 

})

Most of the errors i get have to do with expected character vector arguments, or atomic vectors. I know that shiny is more or less designed to render AND display images or plots but there has to be a way to display pdf's that are already on a local drive..

Awaken answered 19/10, 2013 at 19:11 Comment(2)
may not be related, but you can use / for paths instead of \\ even in windowsHoracehoracio
I think there is no ready made component at the moment. But of course you can display pdf in a webpage. If it can be done in a webapge then shiny can be adapted to do it. See github.com/mozilla/pdf.jsCribbage
S
37

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.

Soldiery answered 9/1, 2014 at 15:55 Comment(2)
An FYI: in my experience using this method, you need to open the Shiny app in a browser to actually see the PDF. It doesn't display in the RStudio window.Obstetrician
Is there anyway to secure the www folder? or to preview PDFs without use of the www I want to be able to preview pictures/pdfs in an iframe type manner, without producing an unsecure URL link that anyone can potentially accessLevina
I
10

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")
    )
  )
))
Infringement answered 9/8, 2017 at 21:28 Comment(1)
Simple answer that works, +1! One comment though: if the file is static (does not change based on user input), you can add the tags$iframe() directly in the UI part, no need to use renderUI() and uiOutput().Headpin
N
4

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.
Nedry answered 5/3, 2019 at 18:34 Comment(1)
You can also run it from the command line, e.g., runApp('maintask',host = "0.0.0.0") if you wanted it to be externally visible. And I believe any R Shiny application is an R Shiny Web Application.Atrium

© 2022 - 2024 — McMap. All rights reserved.