R Shiny - downloadHandler

..Hi,
I want to use the downloadHandler to print a data frame to a PNG file but the code below just produces an empty output file.

Not sure what I'm doing wrong?

Any help would be great.
Thanks.

    output$down_data <- downloadHandler(
        filename = "odata.png",
       content = function(file) {
    
    png(file)
    
    indata <- renderTable({
      
      ddata <-data.frame(Question=c('Age', 'BMI'),
                         Answer=c(input$age, input$bmi))
    })
    
    
    output$rtab <- renderText({
      print.data.frame(HTML("<h3>",input$name,"</h3><h4>", "XXXXXXXXXX","</h4>","<br>",indata()))
    })  
    
    dev.off()
    
})

Hi,

Could you please provide a reprex of the issue. A reprex consists of the minimal code and data needed to recreate the issue you're having. You can find instructions how to build and share one here:

From what I see it seems your code is a bit bizarrely organised with output functions within the downloadHandler. I can't make much sense of it. Also, why would you print a data frame to a picture instead of a csv? You cannot select data from a picture, so that's not a great way to store it. I'm sure you have a reason though, just curious...

PJ

Hi,

I ran the code below and it works but the png file is empty.

library(shiny)
library(ggplot2)
library(lubridate)

setwd("XXXXX")


ui <- fluidPage(

  titlePanel(title=h3("XXXXXX")),

  sidebarLayout(

      sidebarPanel(
         (h4(strong("Baseline Information:"))),
         textInput("name", "Full Name", ""),
         numericInput("age",   "Age", ""),
         numericInput("bmi",   "BMI", ""),
        submitButton("SUBMIT"),
        p("Press SUBMIT to Calculated "),
    ),

 mainPanel(
     tabsetPanel(type = "tabs",
          tabPanel("Patient Data", tableOutput("rtab"), downloadButton("down_data","Download Data"))
  )
  )
  )
  ) 


 server <- function(input, output) {
      output$ptname <- renderText({
      paste(input$name)
 })

indata <- renderTable({

     ddata <-data.frame(Question=c('Age', 'BMI'),
                                     Answer=c(input$age, input$bmi))
})


output$rtab <- renderText({
    dtm <- reactive({
        paste("[",format(now(),"%Y-%m-%d %H:%M"),"]")
 })

HTML("<h3>",input$name,"</h3><h4>","PPPPPPP","</h4>","<br>",indata(),"<br>",dtm(),"<br>"," 
     <br>")
 })  

output$down_data <- downloadHandler(
    filename = "odata.png",
    content = function(file) {
  
    png(file)
  
        indata <- renderTable({
   
            ddata <-data.frame(Question=c('Age', 'BMI'),
                                           Answer=c(input$age, input$bmi))
        })
  
        output$rtab <- renderText({
         print.data.frame(HTML("<h3>",input$name,"</h3><h4>", "PPPPP","</h4>","<br>",indata()))
     })  
  
      dev.off()     
    })
}

runApp(shinyApp(ui, server), launch.browser = TRUE)

Hello,

It was a bit of a challenge, but here is the result:

library(shiny)
library(ggplot2)
library(lubridate)
library(webshot)

ui <- fluidPage(
  
  titlePanel(title=h3("XXXXXX")),
  
  sidebarLayout(
    
    sidebarPanel(
      (h4(strong("Baseline Information:"))),
      textInput("name", "Full Name", ""),
      numericInput("age",   "Age", ""),
      numericInput("bmi",   "BMI", ""),
      submitButton("SUBMIT"),
      p("Press SUBMIT to Calculated ")
    ),
    
    mainPanel(
      tabsetPanel(type = "tabs",
                  tabPanel("Patient Data", 
                           tableOutput("rtab"), 
                           downloadButton("down_data","Download Data")
                           )
      ),
      imageOutput("myImg")
    )
  )
) 


server <- function(input, output) {
  output$ptname <- renderText({
    paste(input$name)
  })

  indata <- renderTable({

    ddata <-data.frame(Question=c('Age', 'BMI'),
                       Answer=c(input$age, input$bmi))
  })


  output$rtab <- renderText({
    HTML("<h3>",input$name,"</h3><h4>","PPPPPPP","</h4>","<br>",indata(),
    "<br>",paste("[",format(now(),"%Y-%m-%d %H:%M"),"]"),"<br>","
     <br>")
  })
  

  output$down_data <- downloadHandler(
    filename = "odata.png",
    content = function(file) {
      write(HTML("<div class='toSave' style='background-color:white; border: 1px solid black;
               padding: 10px 10px; display: inline-block;'><h3>",
                 input$name, "</h3><h4>","PPPPPPP","</h4>","<br>",indata(),"<br>",
                 paste("[",format(now(),"%Y-%m-%d %H:%M"),"]</div>")), file = "htmlImage.html")
      
      webshot(url = "htmlImage.html", file = file, selector = ".toSave")
    })
}

shinyApp(ui, server)

odata

  • I created a separate HTML file containing only the data needed in the image
  • I used the webshot package to capture html output from that page and convert it to an image
  • Note that I used some CSS styling to ensure the final image looks good

Hope this helps,
PJ

Hi Thanks for the reply.

When I try running this on my system I get ther following message:

  "Warning: Error in supervisor_start: processx supervisor was not ready after 5 seconds.
        [No stack trace available]"

Have you seen this before ?

Thanks

Hi,

I have not seen this error message before. Did you get this when you just copy-pasted my complete code and run it into a new app? Because if this is after you modified it, it could be again a different issue...

PJ

Hi PJ,
Thanks, I seemed to have finally sorted out the error message.

Is it possible just to print all the information on the page, rather than specific bit?

Again appreciate your help.