Search code examples
rpdfshinykablekableextra

Exporting save_kable as pdf in Shiny


I'm attempting to export a kable table (latex) to a .pdf file using R Shiny.

Here is the code I am using to generate the kable latex table:

x<-kable(overall, align = c('l', 'c', 'c', 'c', 'c', 'c', 'c'), "latex", booktabs = T,
             caption = "Sample Table",  
             escape = FALSE)%>%
      kable_styling(latex_options = c("striped")) %>%
      add_header_above(c(" " = 1, 'Group 1' = 3, 'Group 2' = 3))%>%
      landscape()

save_kable(x, 'SampleTable.pdf')

I'm able to export this in a standalone R program, but I'd like to replicate the export with R Shiny. I attempted to wrap the code in the downloadHandler function, but it doesn't work.

Sample code:

output$export = downloadHandler(
    filename = function() {"sampleTable.pdf"},
    content = function(file) {
     x<-kable(overall, align = c('l', 'c', 'c', 'c', 'c', 'c', 'c'), "latex", booktabs = T,
         caption = "Sample Table",  
         escape = FALSE)%>%
  kable_styling(latex_options = c("striped")) %>%
  add_header_above(c(" " = 1, 'Group 1' = 3, 'Group 2' = 3))%>%
  landscape()

  save_kable(x, file)
    }
  )

Any insight would be appreciated.


Solution

  • This works for me (after installing pandoc and texlive-xetex):

    
    library(shiny)
    library(knitr)
    library(kableExtra)
    
    library(datasets)
    options(knitr.table.format = "latex") # not required in newer versions of kableExtra
    
    server <- function(input, output) {
    
        # Fill in the spot we created for a plot
        output$phonePlot <- renderPlot({
    
            # Render a barplot
            barplot(WorldPhones[,input$region]*1000, 
                    main=input$region,
                    ylab="Number of Telephones",
                    xlab="Year")
        })
        output$export = downloadHandler(
            filename = function() {"sampleTable.pdf"},
            content = function(file) {
                x <- kable(WorldPhones, align = c('l', 'c', 'c', 'c', 'c', 'c', 'c'), "latex", booktabs = T,
                         caption = "Sample Table",  
                         escape = FALSE) %>%
                    kable_styling(latex_options = c("striped")) %>%
                    add_header_above(c(" " = 1, 'Group 1' = 3, 'Group 2' = 3)) %>%
                    landscape()
    
                save_kable(x, file)
            },
            contentType = 'application/pdf'
        )
    
    }
    
    ui <- fluidPage(    
    
        # Give the page a title
        titlePanel("Telephones by region"),
    
        # Generate a row with a sidebar
        sidebarLayout(      
    
            # Define the sidebar with one input
            sidebarPanel(
                selectInput("region", "Region:", 
                            choices=colnames(WorldPhones)),
                hr(),
                helpText("Data from AT&T (1961) The World's Telephones."), 
                shiny::downloadButton("export", "Export")
            ),
    
            # Create a spot for the barplot
            mainPanel(
                plotOutput("phonePlot")  
            )
    
        )
    )
    
    shinyApp(ui = ui, server = server)