Set caption value in a flextable. The function can also be used to define formattings that will be applied if possible to Word and HTML outputs.

  • The caption will be associated with a paragraph style when the output is Word. It can also be numbered as a auto-numbered Word computed value.

  • The PowerPoint format ignores captions. PowerPoint documents are not structured and do not behave as HTML documents and paginated documents (word, pdf), and it's not possible to know where we should create a shape to contain the caption (technically it can't be in the PowerPoint shape containing the table).

When working with 'R Markdown' or 'Quarto', the caption settings defined with set_caption() will be prioritized over knitr chunk options.

Caption value can be a single string or the result to a call to as_paragraph(). With the latter, the caption is made of formatted chunks whereas with the former, caption will not be associated with any formatting.

  caption = NULL,
  autonum = NULL,
  word_stylename = "Table Caption",
  style = word_stylename,
  fp_p = NULL,
  align_with_table = TRUE,
  html_classes = NULL,
  html_escape = TRUE



flextable object


caption value. The caption can be either a string either a call to as_paragraph(). In the latter case, users are free to format the caption with colors, italic fonts, also mixed with images or equations. Note that Quarto does not allow the use of this feature.

Caption as a string does not support 'Markdown' syntax. If you want to add a bold text in the caption, use as_paragraph('a ', as_b('bold'), ' text') when providing caption.


an autonum representation. See officer::run_autonum(). This has an effect only when the output is "Word" (in which case the object is used to define the Word auto-numbering), "html" and "pdf" (in which case only the bookmark identifier will be used). If used, the caption is preceded by an auto-number sequence.

word_stylename, style

'Word' style name to associate with caption paragraph. These names are available with function officer::styles_info() when output is Word. Argument style is deprecated in favor of word_stylename. If the caption is defined with as_paragraph(), some of the formattings of the paragraph style will be replaced by the formattings associated with the chunks (such as the font).


paragraph formatting properties associated with the caption, see fp_par(). It applies when possible, i.e. in HTML and 'Word' but not with bookdown.


if TRUE, caption is aligned as the flextable, if FALSE, fp_p will not be updated and alignement is as defined with fp_p. It applies when possible, i.e. in HTML and 'Word' but not with bookdown.


css class(es) to apply to associate with caption paragraph when output is 'Word'.


should HTML entities be escaped so that it can be safely included as text or an attribute value within an HTML document.


The values defined by set_caption() will be preferred when possible, i.e. the caption ID, the associated paragraph style, etc. Why specify "where possible"? Because the principles differ from tool to tool. Here is what we have noticed and tried to respect (if you think we are wrong, let us know):

  • Word and HTML documents made with 'rmarkdown', i.e. with rmarkdown::word_document() and rmarkdown::html_document() are not supposed to have numbered and cross-referenced captions.

  • PDF documents made with 'rmarkdown' rmarkdown::pdf_document() automatically add numbers before the caption.

  • Word and HTML documents made with 'bookdown' are supposed to have numbered and cross-referenced captions. This is achieved by 'bookdown' but for technical reasons, the caption must not be defined in an HTML or XML block. So with flextable we lose the ability to format the caption content; surprisingly this is not the case with PDF.

  • HTML and PDF documents created with Quarto will manage captions and cross-references differently; Quarto will replace captions with tbl-cap and label values.

  • Word documents made with Quarto are another specific case, Quarto does not inject captions from the tbl-cap and label values. This is a temporary situation that should evolve later. flextable' will evolve according to the evolution of Quarto.

Using body_add_flextable() enable all options specified with set_caption().

R Markdown

flextable captions can be defined from R Markdown documents by using knitr::opts_chunk$set(). User don't always have to call set_caption() to set a caption, he can use knitr chunk options instead. A typical call would be:

#| bookmark_id
#| tab.cap: caption text
flextable(head(cars)) is the caption id or bookmark, tab.cap is the caption text. There are many options that can replace set_caption() features. The following knitr chunk options are available:

Word stylename to use for table
caption id/bookmarktab.idNULL
display table caption on top of the table or nottab.topcaptionTRUE
caption table sequence"tab:"
prefix for numbering chunk (default to "Table ").tab.cap.preTable
suffix for numbering chunk (default to ": ").tab.cap.sep" :"
title number depthtab.cap.tnd0
separator to use between title number and table"-"
caption prefix formatting propertiestab.cap.fp_textfp_text_lite(bold = TRUE)

See knit_print.flextable for more details.

Formatting the caption

You can build your caption with as_paragraph(). This is recommended if your captions need complex content. The caption is build with a paragraph made of chunks (for example, a red bold text + Arial italic text).

The user will then have the ability to format text and to add images and equations. If no format is specified (using "a string" or as_chunk("a string")), fp_text_default() is used to define font settings (font family, bold, italic, color, etc...). The default values can be changed with set_flextable_defaults(). It is recommended to explicitly use as_chunk().

The counterpart is that the style properties of the caption will not take precedence over those of the formatted elements. You will have to specify the font to use:

ftab <- flextable(head(cars)) %>%
      as_chunk("caption", props = fp_text_default( = "Cambria"))
    ), word_stylename = "Table Caption")
print(ftab, preview = "docx")

Using 'Quarto'

'Quarto' manage captions and cross-references instead of flextable. That's why set_caption() is not that useful in a 'Quarto' document except for Word documents where 'Quarto' does not manage captions yet (when output is raw xml which is the case for flextable).

knitr options are almost the same than those detailled in the R Markdown section (see upper), but be aware that 'Quarto' manage captions and it can be overwrite what has been defined by flextable. See Quarto documentation for more information.

See also


ftab <- flextable( head( iris ) )
ftab <- set_caption(ftab, "my caption")
#> a flextable object.
#> col_keys: `Sepal.Length`, `Sepal.Width`, `Petal.Length`, `Petal.Width`, `Species` 
#> header has 1 row(s) 
#> body has 6 row(s) 
#> original dataset sample: 
#>   Sepal.Length Sepal.Width Petal.Length Petal.Width Species
#> 1          5.1         3.5          1.4         0.2  setosa
#> 2          4.9         3.0          1.4         0.2  setosa
#> 3          4.7         3.2          1.3         0.2  setosa
#> 4          4.6         3.1          1.5         0.2  setosa
#> 5          5.0         3.6          1.4         0.2  setosa

autonum <- run_autonum(seq_id = "tab", bkm = "mtcars")
ftab <- flextable( head( mtcars ) )
ftab <- set_caption(ftab, caption = "mtcars data", autonum = autonum)
#> a flextable object.
#> col_keys: `mpg`, `cyl`, `disp`, `hp`, `drat`, `wt`, `qsec`, `vs`, `am`, `gear`, `carb` 
#> header has 1 row(s) 
#> body has 6 row(s) 
#> original dataset sample: 
#>                    mpg cyl disp  hp drat    wt  qsec vs am gear carb
#> Mazda RX4         21.0   6  160 110 3.90 2.620 16.46  0  1    4    4
#> Mazda RX4 Wag     21.0   6  160 110 3.90 2.875 17.02  0  1    4    4
#> Datsun 710        22.8   4  108  93 3.85 2.320 18.61  1  1    4    1
#> Hornet 4 Drive    21.4   6  258 110 3.08 3.215 19.44  1  0    3    1
#> Hornet Sportabout 18.7   8  360 175 3.15 3.440 17.02  0  0    3    2