Search code examples
rshinyofficergt

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

  • 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