A FAQ and known issues
A.1 Which function should I use to format cell content?
There are two levels of cell content formatting:
colformat_*()functions (colformat_double(),colformat_int(),colformat_char(), etc.) apply simple formatting to entire columns. Use them for straightforward needs such as changing the number of decimal places or adding a prefix/suffix. Note thatcolformat_num()does not accept adigitsargument; it uses R’s defaultformat().mk_par()(or its aliascompose()) lets you build rich cell content by concatenating chunks of text, images, and mini charts insideas_paragraph(). Use it when you need to mix formatting within a single cell.
mk_par() and compose() are the same function. Prefer mk_par() to
avoid the name conflict with purrr::compose(). You can also use
flextable::compose() with the namespace prefix.
To add content to an existing paragraph rather than replacing it, use
append_chunks() or prepend_chunks().
A.2 Why does my table look different in PDF?
The PDF output relies on LaTeX and has several limitations:
-
Padding is ignored. Use the knitr chunk options
ft.tabcolsepandft.arraystretchto control spacing instead. - Borders can only be solid lines (no dashed or dotted styles).
- Row height cannot be defined.
-
Fonts: to use system fonts, add
latex_engine: xelatexin the YAML header of the R Markdown document. The default enginepdflatexdoes not support system fonts. -
Rotation:
rotate()is not supported in PDF/LaTeX output. -
Page breaks within a row: a table row whose content is taller than a
page cannot be split across pages. This is a fundamental constraint of
LaTeX’s
longtableenvironment.
A.3 Can I insert images or ggplots in PowerPoint tables?
No. PowerPoint does not support images inside table cells. This is a PowerPoint limitation, not a flextable limitation. The same restriction applies to ggplot charts and mini charts.
Workaround: use save_as_image() or plot() to render the table
as an image and insert that image into the slide. You will lose the ability
to edit the table in PowerPoint.
A.4 How do I control table width?
Two layout modes are available via set_table_properties():
-
layout = "fixed"(default): you control column widths manually withwidth(). The table renders identically in Word, HTML, PDF and PowerPoint. -
layout = "autofit": the table width is computed automatically. You can setwidth = 1to fill the available width. Supported in HTML, Word and PDF but not in PowerPoint.
A.5 Why is autofit() making my table overflow the margins?
autofit() computes the minimal column widths needed to fit the content on
a single line. It does not take into account the page width of the output
document. For long text, columns may exceed the page margins.
To make the table fit within the page, use
set_table_properties(layout = "autofit") instead. This enables the Word
autofit algorithm which respects page margins. Despite the similar name,
autofit() and set_table_properties(layout = "autofit") are different:
-
autofit()sets column widths to the minimum needed (a flextable function). -
set_table_properties(layout = "autofit")lets Word/HTML/PDF compute optimal widths within the available space (a document layout setting).
A.6 Do tab stops work in HTML?
No. Tab stops set with tab_settings() only take effect in Word and RTF
outputs. In HTML, the \t characters are rendered as regular whitespace.
A.7 How do I keep rows together across pages in Word?
Use paginate() to prevent page breaks from splitting the table in
unfortunate places. See the Rendering chapter for detailed examples with
init, hdr_ftr, and group arguments.
For fine-grained control over individual rows, use keep_with_next().
A.8 How do I use flextable in Shiny?
Use htmltools_value() to get the HTML representation of the flextable,
then display it with shiny::uiOutput():
output$my_table <- renderUI({
htmltools_value(my_flextable)
})A.9 Do I need officedown for Word output from R Markdown?
If your table contains images or hyperlinks and you render to Word,
you should use officedown::rdocx_document() instead of
rmarkdown::word_document(). Pandoc does not handle images and hyperlinks
inside raw blocks.
For tables with only text content, rmarkdown::word_document() works fine.
A.10 Why does height() have no effect?
height() only works when the row height rule is set to "exact" or
"atleast" via hrule(). The default rule is "auto", which determines
height from the content and ignores height() values.
Exception: PowerPoint does not support automatic line height, so height()
always takes effect there.
A.11 Can I use formula selectors with header rows?
Row selectors expressed as formulas (e.g. i = ~ variable > 5) cannot be
used when part = "header" or part = "all". Use integer row indices
instead for header and footer parts.
A.12 How do I add hyperlinks in a table?
Use hyperlink_text() inside mk_par() to create clickable links:
mk_par(ft, j = "url", value = as_paragraph(
hyperlink_text(x = label, url = url)
))In Word, use officedown::rdocx_document() instead of
rmarkdown::word_document() for hyperlinks to work correctly.
A.13 Can I format captions with markdown?
No. Captions set with set_caption() do not support markdown syntax. Use
flextable chunk formatting functions instead: as_b(), as_i(),
as_chunk(), as_equation(), etc.
A.14 Does flextable work with Quarto?
flextable works with Quarto for HTML and Word outputs. However, there are known limitations:
- Captions: use
set_caption()for proper numbering. Caption formatting may be stripped in some Quarto versions. - Links and Cross-references: not yet supported.
- Images in Word: inserting images in flextable cells produces corrupted Word documents when rendered through Quarto. This is a known issue.
A.15 Does flextable support github_document output?
Yes, since version 0.9.3. The table is automatically rendered as an image
in github_document and other GFM outputs.
A.16 How do I add line breaks inside a cell?
A flextable cell contains a single paragraph. The \n character creates
a soft return (line break within the same paragraph), not a new paragraph.
To insert line breaks, prefer mk_par() with multiple chunks or
append_chunks() rather than embedding \n in your data.