In Quarto, use `tbl-cap` and `label` chunk options for captions and cross-references. The `set_caption()` function is less useful in Quarto because Quarto manages captions itself.
### R Markdown chunk options
```r
knitr::opts_chunk$set(
ft.align = "center", # table alignment: "left", "center", "right"
ft.split = TRUE # allow Word rows to break across pages
)
```
Common per-chunk options:
| Option | Format | Description |
|---|---|---|
| `ft.align` | All | Table alignment (`"left"`, `"center"`, `"right"`) |
| `ft.split` | Word | Allow rows to break across pages |
| `ft.htmlscroll` | HTML | Enable horizontal scrolling |
| `ft.tabcolsep` | PDF | Space between text and cell borders (pt) |
| `ft.arraystretch` | PDF | Row height multiplier (default 1.5) |
| `ft.latex.float` | PDF | Float placement (`"none"`, `"float"`, `"wrap-r"`, etc.) |
| `ft.left`, `ft.top` | PowerPoint | Table position in inches |
### Printing inside loops
When generating tables inside a `for` loop in R Markdown, use `flextable_to_rmd()` with `results='asis'`:
```r
# In a chunk with results='asis'
for (nm in names(split_data)) {
flextable_to_rmd(flextable(split_data[[nm]]))
}
```
## HTML
### Save to a standalone HTML file
```r
ft1 <- flextable(head(iris)) |> theme_vanilla() |> autofit()
tf <- tempfile(fileext = ".html")
save_as_html(ft1, path = tf)
```
Pass multiple tables as named arguments — names become section headings:
```r
save_as_html(
`Iris data` = ft1,
`Mtcars data` = ft2,
path = "tables.html",
title = "My Tables"
)
```
### Use in Shiny
`htmltools_value()` returns an `htmltools` tag object suitable for `shiny::renderUI()`:
```r
library(shiny)
library(flextable)
ui <- fluidPage(
uiOutput("table_out")
)
server <- function(input, output, session) {
output$table_out <- renderUI({
ft <- flextable(head(iris)) |> autofit()
htmltools_value(ft)
})
}
```
<Note>
HTML output uses Shadow DOM to isolate table styles from the host page. This prevents conflicts with existing CSS but means the table's styles are scoped to a shadow root.
</Note>
## Word (DOCX)
### Save to a standalone Word file
```r
library(officer)
ft <- flextable(head(iris)) |> theme_vanilla() |> autofit()
save_as_docx(ft, path = "my_table.docx")
```
Control page layout with `officer::prop_section()`:
```r
sect_properties <- prop_section(
page_size = page_size(orient = "landscape", width = 8.3, height = 11.7),
type = "continuous",
page_margins = page_mar()
)
save_as_docx(
`Iris data` = ft1,
`Mtcars data` = ft2,
path = "tables.docx",
pr_section = sect_properties
)
```
### Embed in an officer Word document
For full control — including captions, bookmarks, and document flow — use `officer` directly:
```r
library(officer)
doc <- read_docx() |>
body_add_par("Table 1: Iris sample", style = "heading 2") |>
body_add_flextable(ft, align = "center")
print(doc, target = "report.docx")
```
`body_add_flextable()` respects all `set_caption()` settings, including auto-numbering via `officer::run_autonum()`, paragraph styles, and caption position.
## PowerPoint (PPTX)
### Save to a standalone PowerPoint file
```r
ft1 <- flextable(head(iris))
tf <- tempfile(fileext = ".pptx")
save_as_pptx(ft1, path = tf)
```
Named arguments become slide titles:
```r
save_as_pptx(
`Iris table` = ft1,
`Mtcars table` = ft2,
path = tf
)
```
### Embed in an officer PowerPoint document
Use `officer::ph_with()` for precise placement:
```r
library(officer)
ft <- flextable(head(iris))
doc <- read_pptx() |>
add_slide("Title and Content", "Office Theme") |>
ph_with(ft, location = ph_location_left())
print(doc, target = "slides.pptx")
```
<Note>
PowerPoint only supports fixed table layout. Use `autofit()` to adjust column widths. Images inside table cells are not supported — this is a PowerPoint limitation. Captions are also ignored in PowerPoint output.
</Note>
## RTF
```r
library(officer)
ft <- flextable(head(iris)) |> theme_vanilla() |> autofit()
tf <- tempfile(fileext = ".rtf")
save_as_rtf(ft, path = tf)
```
Like `save_as_docx()`, pass a `prop_section` object to control page layout and add page headers:
```r
sect_properties <- prop_section(
page_size = page_size(orient = "landscape", width = 8.3, height = 11.7),
type = "continuous",
page_margins = page_mar(),
header_default = block_list(
fpar(ftext("text for default page header"))
)
)
tf <- tempfile(fileext = ".rtf")
save_as_rtf(
`Iris table` = ft1,
`Mtcars table` = ft2,
path = tf,
pr_section = sect_properties
)
```
## PDF and LaTeX
flextable generates LaTeX via knitr. No separate save function is needed — place a flextable in a code chunk in an R Markdown or Quarto document with PDF output: