Chapter 4 Rendering

Tables created as ‘flextable’ objects can be rendered in several formats: HTML, Word, RTF, PowerPoint, PDF, PNG. The package offers simple export functions, works inside ‘R Markdown’ and ‘Quarto’ documents and works with the ‘officer’ package.

When working in RStudio, flextable will be printed in the rstudio viewer pane as an HTML table, the default format is HTML output.

4.1 Simple export

It is possible to easily export one or more tables into Word, RTF, PowerPoint, PNG and HTML documents. Each format has its own dedicated function.

Functions save_as_html(), save_as_pptx(), save_as_rtf() and save_as_docx() can be used to export one or more ‘flexables’ into a document. Function save_as_image() can only be used to export a single ‘flextable’.

save_as_docx(
  "my table 1" = ft1, "my table 2" = ft2, 
  path = "/path/to/file.docx")

save_as_rtf(
  "my table 1" = ft1, "my table 2" = ft2, 
  path = "/path/to/file.rtf")

save_as_pptx(
  "my table 1" = ft1, "my table 2" = ft2,
  path = "/path/to/file.pptx")

save_as_html(
  "my table 1" = ft1, "my table 2" = ft2,
  path = "/path/to/file.html")

save_as_image(ft, path = "/path/to/file.png")

4.2 In RStudio

In RStudio, the HTML version is displayed in the Viewer pane.

If you have a Word or PowerPoint client on your machine, you can use the print method with argument preview set to “pptx”, “docx”, “rtf”, “pdf” or “html” the default. It will produce and open a document where the table will be printed.

print(ft, preview = "docx")
print(ft, preview = "rtf")
print(ft, preview = "pptx")
print(ft, preview = "pdf")
print(ft, preview = "html")

4.3 R Markdown documents

flextable can be used in R Markdown documents. The printing a flextable in R Markdown documents is done automatically. 1

The following R Markdown document shows how to use flextable:

---
title: blah blah
output: html_document
---

> this is how to print a flextable in a R Markdown document

```{r}
library(flextable)
ft <- flextable(head(mtcars))
ft <- autofit(ft)
ft
```

Supported formats require some minimum pandoc versions:

Output format

pandoc version

HTML

>= 1.12

Word (docx)

>= 2.0

PowerPoint (pptx)

>= 2.4

PDF

>= 1.12

4.3.1 Knitr Chunk options

There are knitr chunk options that can be used to help with captions and table properties.

These options should be set with knitr::opts_chunk$set():

  • knitr chunk options for table captions:
    • tab.id: caption id/bookmark (default to NULL)
    • tab.cap: caption (default to NULL)
    • tab.topcaption: display table caption on top of the table or not (default to TRUE)
    • tab.lp: caption table sequence identifier: (default to “tab:”)
  • knitr chunk options for Word table captions:
    • tab.cap.style: Word stylename to use for table captions (default to NULL)
    • tab.cap.pre: prefix for numbering chunk (default to “Table”)
    • tab.cap.sep: suffix for numbering chunk (default to “:”)
    • tab.cap.tnd: title number depth (default to 0)
    • tab.cap.tns: separator to use between title number and table number (default to “-”)
    • tab.cap.fp_text: caption prefix formatting properties (default to fp_text_lite(bold = TRUE))
  • knitr chunk options for Word tables:
    • tab.layout: “autofit” or “fixed” algorithm (default to “autofit”)
    • tab.width: value of the preferred width of the table in percent (default to 1)

4.3.2 Looping in R Mardown documents

Some code will not trigger the knitr::knit_print() method. For example this is the case inside of a for loop within an R code chunk.

In this case, you can use knitr::knit_child() that will print the raw code adapted to the output format. Chunk option results must be set to asis.

When using knitr::knit_child(), the LaTeX and HTML dependencies required to render the content from the included file are automatically detected and integrated into the parent document. This means that if your included file contains elements that require specific LaTeX or HTML packages (this is the case for ‘flextable’), knitr::knit_child() will ensure that all these dependencies are properly handled and included in the final document.

Note the old function flextable_to_rmd() does not directly handle LaTeX and HTML dependencies and should not be used anymore.

Here is an illustration. We will need two files:

  • the child document child-loop.Rmd
```{r echo=FALSE}
library(flextable)
flextable::flextable(head(dat)) |> 
  set_table_properties(layout = "autofit") |> 
  set_caption(caption = caption)
```
  • and the main document rmd-print-loop.Rmd.
---
title: blah blah
output: word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE)
library(flextable)
```

> this is how to print flextables in a loop in a R Markdown document

```{r results='asis', echo=FALSE}
purrr::map2_chr(
  .x = c("cars", "iris"),
  .y = list(cars, iris), 
  function(caption, dat) {
    knitr::knit_child(input = "child-loop.Rmd", envir = environment(), quiet = TRUE)
  }) |> 
  cat(sep = '\n')
```

4.3.3 Limitations

  • This limitation concerns the usage of ‘flextable’ in a ‘R Markdown’ document with ‘Word’ as output format. If you use hyperlinks or images in the table, you should use officedown::rdocx_document() instead of rmarkdown::word_document(). ‘pandoc’ does not provide a mechanism for handling images nor hyperlinks from raw blocks and therefore it is not possible with ‘R Markdown’.

  • The PDF version of the flextable ignore some features of flextable, here is the list of unsupported/ignored options (they may be implemented later):

    • padding is not taken into account (it is instead recommended to use the arguments ft.tabcolsep and ft.arraystretch),
    • the borders can only be full (no dash for example),
    • the height of the lines cannot be defined.
    • In order to be able to change latex font in a flextable, PDF engine should be specified by adding latex_engine: xelatex in the YAML header of the R Markdown document. The default one pdflatex does not enable the use of system fonts.

4.4 PowerPoint or Word documents with officer

To add these objects in PowerPoint or Word documents, use functions:

The following is producing a PowerPoint document:

library(officer)
ft1 <- qflextable(head(airquality))
ft2 <- as_flextable(cars)

ppt <- read_pptx()
ppt <- add_slide(ppt, layout = "Title and Content", master = "Office Theme")
ppt <- ph_with(ppt, value = ft1, location = ph_location_left()) 
ppt <- ph_with(ppt, value = ft2, location = ph_location_right()) 

print(ppt, target = "reports/example_table_powerpoint.pptx")

If you want to center the flextable on a PowerPoint slide, it’s up to you to do the calculation. For that, you can use functions flextable::flextable_dim and officer::slide_size:

ppt <- read_pptx()
ppt <- add_slide(ppt, layout = "Title and Content", master = "Office Theme")

t_s <- flextable_dim(ft1)$widths
s_s <- slide_size(ppt)$width
left <- (s_s/2) - (t_s/2) 

ppt <- ph_with(ppt, value = ft1, location = ph_location(left = left, top = 1.5)) 

print(ppt, target = "reports/example_table_powerpoint_center.pptx")

The following is producing a Word document:

read_docx() %>% 
  body_add_par("A first table") %>% 
  body_add_flextable(value = ft1) %>% 
  body_add_par("A second table") %>% 
  body_add_flextable(value = ft2) %>% 
  print(target = "reports/example_table_word.docx")

4.5 Using within shiny applications

Use function htmltools_value() to get the html value of the flextable. This value is suitable for an shiny::uiOutput().

library(shiny)
library(flextable)
library(dplyr)

dat <- mtcars %>%
  mutate(car = rownames(.)) %>%
  select(car, everything())

ui <- fluidPage(
  titlePanel("mtcars"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("mpg", "mpg Limit", min = 11, max = 33, value = 20)
    ),
    mainPanel(uiOutput("mtcars_ft"))
  )
)

server <- function(input, output) {
  output$mtcars_ft <- renderUI({
    req(input$mpg)
    filter(dat, mpg <= input$mpg) %>%
      flextable() %>%
      theme_vader() %>%
      autofit() %>%
      htmltools_value()
  })
}

# Run the application
shinyApp(ui = ui, server = server)

4.6 Automatic printing of data.frame as flextable

The package is providing an S3 method to automatically print R data.frame as flextables. All you need is to call use_df_printer() in an R code chunk. It will register df_print() as the method to use for printing data.frames.

df_print() creates a summary from a data.frame as a flextable. It display first lines and show column types. In addition to usual knitr chunk options, the following options are also available:

  • ft_max_row: The number of rows to print. Default is 10.
  • ft_split_colnames: Should the column names be split (with non alpha-numeric characters). Default is FALSE.
  • ft_short_strings: Should the character column be shortened. Default is FALSE.
  • ft_short_size: Maximum length of character column if ft_short_strings is TRUE. Default is 35.
  • ft_short_suffix: Suffix to add when character values are shorten. Default is “…”.
  • ft_do_autofit: Use autofit() before rendering the table. Default is TRUE.
  • ft_show_coltype: Show column types. Default is TRUE.
  • ft_color_coltype: Color to use for column types. Default is “#999999”.

The chapter 15) presenting the example datasets is an illustration of use_df_printer() usage.

---
output: word_document
---

```{r setup, include=FALSE}
knitr::opts_chunk$set(echo = FALSE, ft_max_row = 6, tab.topcaption=FALSE, ft.align="left")
library(flextable)
set_flextable_defaults(font.size = 11, padding = 3)
use_df_printer()
```

This is blah blah blah.

```{r tab.cap="cars"}
cars
```

This is blah blah blah.

```{r tab.cap="airquality"}
airquality
```


  1. HTML, Word, PowerPoint and PDF outputs are managed with method knitr::knit_print. For markdown output, an image is used.↩︎