Search code examples
rggplot2shinyxlsxshiny-server

Putting images into xlsx docs through Shiny on shiny-server


I believe I'm running into permission issues between a working shiny app running though RStudio on my laptop and shiny-server on ubuntu.

This sample app for instance will write an image in an xlsx doc and let you download the xlsx. It will work in rstudio running shiny locally but not through shiny-server. I'm guessing that there is a way to write the png in a secure way temporarily and call it back for writing to the xlsx that is kosher with shiny-server.

server.R

library(shiny);library(openxlsx);library(ggplot2)

shinyServer(function(input, output) {

  output$downloadReport <- downloadHandler(
    filename = "test.xlsx",
    content = function(file){
      wb <- createWorkbook(paste0(Sys.time(), ".xlsx"))
      my_plot <- ggplot(mtcars) + geom_line(aes(x = cyl, y = gear))
      worksheet_name <- "ggplot"

      addWorksheet(wb, worksheet_name)
      png("plot.png", width=1024, height=768, units="px", res=144)
      print(my_plot)
      dev.off()  
      insertImage(wb, worksheet_name, "plot.png", width=11.18, height=7.82, units="in")

      saveWorkbook(wb, file, overwrite = TRUE)
    })
})

ui.R

library(shiny)

shinyUI(fluidPage(
  sidebarLayout(
    sidebarPanel(
      helpText(),
      downloadButton('downloadReport')),
    mainPanel()
  ))
)

Solution

  • Taking the hint from ralf-stubner, I changed

    png("plot.png", width=1024, height=768, units="px", res=144)
    

    to

    png(paste0(tempdir(), "/", "plot.png"), width=1024, height=768, units="px", res=144)
    

    and

    insertImage(wb, worksheet_name, "plot.png", width=11.18, height=7.82, units="in")
    

    to

    insertImage(wb, worksheet_name, paste0(tempdir(), "/", "plot.png"), width=11.18, height=7.82, units="in")
    

    and now the image is written to a temporary directory with the right permissions instead of the app directory, which only worked on my local development laptop.