add gt table image to word doc with shiny and officer package

I am writing a shiny app which:

  • creates a gt table
  • saves the gt table as an image (temporary file)
  • passes that image into a word doc using {officer} package

I am having difficulty with the image creation .... any help appreciated... here is my reprex

library(shiny)
library(gt)
library(dplyr)

ui <- fluidPage(
      
      
      downloadButton("report", "Generate Report")
      
      
)



server <- function(input, output, session) {
      
      
      my_table <- render_gt(
                
                mtcars[1:5,1:5] %>%
                          gt()
      )
      
      my_image <-reactive({
                
                outfile <- tempfile(fileext='.png')
                
                gtsave(my_table, outfile, width = 400, height = 300)
                
                
                
      })
      
      
      
      output$report <- downloadHandler(
                
                filename = function() {
                          "download.docx"
                },
                
                content = function(file) {
                          
                          
                          print(read_docx() %>%
                                          body_add_img(my_image()),
                                target = file)
                          
                          
                },
                contentType = "docx"
                
                
      )
      
      
      
}

shinyApp(ui, server)

Solution 1:

There are several issues with your code:

  1. You use render_gt instead of reactive.
  2. Your reactive my_image does not return the name of the temporary file which is needed to add it to the docx. Additionally, as my_table is or should be a reactive use my_table()
  3. In gtsave use vwidth and vheight. See ?webshot::webshot.
  4. In officer::body_add_img you have to set a width and height in inches.

Reproducible code:

library(shiny)
library(gt)
library(dplyr)
library(officer)

ui <- fluidPage(
  downloadButton("report", "Generate Report")
)

server <- function(input, output, session) {
  my_table <- reactive({
    mtcars[1:5, 1:5] %>%
      gt()  
  })
  
  my_image <- reactive({
    outfile <- tempfile(fileext = ".png")
    gtsave(my_table(), outfile, vwidth = 400, vheight = 300)
    outfile
  })

  output$report <- downloadHandler(
    filename = function() {
      "download.docx"
    },
    content = function(file) {
      read_docx() %>%
        body_add_img(my_image(), width = 4, height = 3) %>%
        print(target = file)
    },
    contentType = "docx"
  )
}

shinyApp(ui, server)

enter image description here