1

I'm trying to physically print an image from a shiny app, I have already read from: RShiny print current page

But, it prints all the window content, I like to send a graph to the printer.

I expect that using shiny JS tools I could print the images of the shiny.

How do I solve the problem?

Emma
  • 27,428
  • 11
  • 44
  • 69
  • 1
    As a workaround you could use a download handler and the users would not click „save“ but „open“ the png and then they could print it from their standard image viewer. It takes two clicks more than printing directly. – TimTeaFan Jul 27 '19 at 06:57
  • I wonder, do you want to print a regular image embedded in your shiny app, or do you want to print a plot which is rendered on server and displayed in your UI? – TimTeaFan Jul 27 '19 at 09:22

1 Answers1

0

Interesting question. Let's assume we want to print a normal image, embedded in a shiny app with tags$img. I tried to approach it in two steps.

  1. How can we print an image via button click in javascript.
  2. How can we bring this approach to shiny.

The first question is answered on SO here. I choose to give the answer with the most upvotes a try.

With shinyjs we can bring javascript functions to shiny.

useShinyjs(),  # Set up shinyjs
shinyjs::extendShinyjs(text = paste0("shinyjs.img_print = function(){",
                                     "popup = window.open();",
                                     "popup.document.write('",tags$img(src = img_url),"');",
                                     "popup.focus();",
                                     "popup.print(); }"))

With observeEvent we can trigger an action via click on an action button.

observeEvent(input$print, {
  shinyjs::js$img_print()
})

Putting it all together in a simple shiny app:

library("shiny")
library("shinyjs")
library("V8")

img_url <-"https://images.unsplash.com/photo-1563169372-eb64c121f9dc?ixlib=rb-1.2.1&ixid=eyJhcHBfaWQiOjEyMDd9&auto=format&fit=crop&w=1561&q=80"

shinyApp(

  ui = fluidPage(

    useShinyjs(),  # Set up shinyjs
    shinyjs::extendShinyjs(text = paste0("shinyjs.img_print = function(){",
                                         "popup = window.open();",
                                         "popup.document.write('",tags$img(src = img_url),"');",
                                         "popup.focus();",
                                         "popup.print(); }")),
    tags$img(src = img_url, 
             alt = "Image 1",
             height = 400,
             width = 300),
    actionButton("print", "Print image")


  ), # closes fluidPage


  # Server ------
  server = function(input, output, session){

    observeEvent(input$print, {
      shinyjs::js$img_print()
    })


  } # Closes server
) # Closes ShinyApp

If you want to print a graph which is rendered on server, then it would be probably necessary to first create a temp image file of the plot and then apply the approach outlined above.

TimTeaFan
  • 17,549
  • 4
  • 18
  • 39