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.

This topic was automatically closed 54 days after the last reply. New replies are no longer allowed.