Skip to main content
flextable integrates with knitr through knit_print.flextable(), which is called automatically when a flextable object appears in a code chunk. You do not need to call it directly.

How rendering works

When knitr processes a chunk containing a flextable, it detects the output format and generates the appropriate output:
Output formatRendering method
HTMLNative HTML table with scoped CSS
Word (docx)Office Open XML (wml)
PDFLaTeX table code
PowerPoint (pptx)Presentation ML (pml)
Other (GitHub, Beamer, etc.)PNG image via save_as_image()
No special setup is required. Place a flextable object in a chunk and it renders:
library(flextable)

ft <- flextable(head(iris))
ft <- autofit(ft)
ft

Adding captions

The recommended way to add a caption is with set_caption():
ft <- flextable(head(airquality))
ft <- set_caption(ft, caption = "Daily air quality measurements")
ft
When set_caption() is used, chunk options related to captions are ignored. In Quarto, use tbl-cap and label chunk options instead of set_caption():
```{r}
#| label: tbl-airquality
#| tbl-cap: "Daily air quality measurements"
ft
```
Cross-references in Quarto use @tbl-airquality. In bookdown documents, cross-references use \@ref(tab:chunk_label).

Chunk options reference

All formats

OptionDescriptionDefault
ft.alignTable alignment: 'left', 'center', 'right''center'

R Markdown captions

These options are only used when set_caption() has not been called on the table:
OptionDescriptionDefault
tab.capCaption textNULL
tab.idCaption id / bookmarkNULL
tab.topcaptionPlace caption above the tableTRUE
tab.lpCaption sequence identifier"tab:"
tab.cap.styleWord paragraph style for the captionNULL

HTML

OptionDescriptionDefault
ft.htmlscrollEnable horizontal scrollingFALSE

Word

OptionDescriptionDefault
ft.splitAllow rows to break across pagesTRUE

PDF

OptionDescriptionDefault
ft.tabcolsepSpace between text and cell borders (pt)0
ft.arraystretchRow height multiplier1.5
ft.latex.floatFloat placement: 'none', 'float', 'wrap-r', 'wrap-l', 'wrap-i', 'wrap-o''none'

PowerPoint

OptionDescriptionDefault
ft.leftLeft position of table placeholder (inches)1
ft.topTop position of table placeholder (inches)2
Set defaults for an entire document with knitr::opts_chunk$set():
knitr::opts_chunk$set(
  ft.align = "left",
  ft.tabcolsep = 4
)

officedown caption options

When using officedown::rdocx_document(), additional caption chunk options become available:
OptionDescriptionDefault
tab.cap.preNumbering prefix"Table "
tab.cap.sepNumbering suffix": "
tab.cap.tndTitle number depth0
tab.cap.fp_textCaption prefix formattingfp_text_lite(bold=TRUE)
tab.cap.tnsTitle / table number separator"-"

Tables inside loops

To print flextable objects inside for loops or if statements, use flextable_to_rmd(). Set the chunk option results = 'asis':
```{r results='asis'}
for (species in unique(iris$Species)) {
  sub <- subset(iris, Species == species)
  ft <- flextable(head(sub))
  ft <- set_caption(ft, caption = as.character(species))
  flextable_to_rmd(ft)
}
```

Automatic data frame conversion

use_df_printer() replaces the default data frame print method so that any data frame printed in a document is automatically converted to a flextable:
use_df_printer()

# now data frames render as flextable
head(iris)
Call use_model_printer() to do the same for model objects. These functions are best placed in a setup chunk.

Quarto setup with use_flextable_qmd()

The flextable-qmd Lua filter extension allows Quarto markdown syntax inside flextable cells: cross-references, bold, italic, links, math, inline code, and shortcodes. Install it with:
use_flextable_qmd()
After installing, use as_qmd() to mark cell content as Quarto markdown:
ft <- flextable(data.frame(
  label = c("See @tbl-summary for details"),
  value = c(42)
))
ft <- compose(
  ft, j = "label",
  value = as_paragraph(as_qmd("See @tbl-summary for details"))
)

Post-processing hooks

set_flextable_defaults() accepts post-processing functions that are applied to every table before rendering. This is useful for applying consistent styling across a document:
set_flextable_defaults(
  post_process_html = function(ft) {
    theme_vanilla(ft)
  },
  post_process_docx = function(ft) {
    theme_booktabs(ft)
  }
)
Available hooks: post_process_all, post_process_html, post_process_docx, post_process_pdf, post_process_pptx.