Skip to main content

Documentation Index

Fetch the complete documentation index at: https://mintlify.com/davidgohel/flextable/llms.txt

Use this file to discover all available pages before exploring further.

flextable can be rendered as a raster or vector image using R’s grid graphics system. This is useful for including tables in presentations, reports, or composite figures.

Save as PNG or SVG

save_as_image() saves a flextable to a PNG or SVG file. The output format is determined by the file extension:
library(gdtools)
library(flextable)

register_liberationsans()
set_flextable_defaults(font.family = "Liberation Sans")

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

tf <- tempfile(fileext = ".png")
save_as_image(x = ft, path = tf)
For SVG output, the svglite package must be installed:
tf_svg <- tempfile(fileext = ".svg")
save_as_image(x = ft, path = tf_svg)
Parameters:
ParameterDescriptionDefault
xA flextable object
pathOutput path ending in .png or .svg
expandWhite space (px) to add around the table10
resResolution of the PNG device (DPI)200
Captions set with set_caption() are not included in image output. Captions are only rendered in document formats (Word, HTML, PDF).

Convert to a grid grob with gen_grob()

gen_grob() converts a flextable to a grob (grid graphics object). This is the function used internally by save_as_image() and the patchwork integration.
library(ragg)
library(gdtools)
register_liberationsans()
set_flextable_defaults(font.family = "Liberation Sans")

ft <- flextable(head(mtcars))
gr <- gen_grob(ft)
plot(gr)

fit argument

Controls how the table adapts to the drawing surface:
ValueBehavior
"auto" (default)Resize table proportionally to fill the viewport
"width"Resize columns to fit viewport width; row heights unchanged
"fixed"Use exact column widths and row heights from the table

scaling argument

Controls how text and content sizes respond to viewport size:
ValueBehavior
"min" (default)Scale content down when viewport is smaller; do not scale up
"full"Scale content up or down to match viewport
"fixed"Never scale content

just argument

Justification of the viewport layout within the drawing area. Accepts the same values as grid::grid.layout(just = ...). When NULL (default), justification is derived from fit.

wrapping argument

When TRUE (default), text wraps at word boundaries. When FALSE, text only wraps at explicit newline characters.

Getting dimensions

Use the dim() method on the grob to retrieve the rendered table size in inches:
gr <- gen_grob(ft, fit = "fixed")
dim(gr)  # returns list with $width and $height
Equations (as_equation()) and hyperlinks (officer::hyperlink_ftext()) are not rendered by gen_grob(). Use a ragg, svglite, or ggiraph device for correct rendering.

Combine with ggplot2 using patchwork

wrap_flextable() wraps a flextable as a patchwork-compatible patch, so it can be combined with ggplot2 plots using +, |, or / operators.
library(gdtools)
font_set_liberation()
library(ggplot2)
library(patchwork)

set_flextable_defaults(
  font.family = "Liberation Sans",
  font.size = 10,
  big.mark = "",
  border.color = "grey60"
)

dataset <- data.frame(
  team = c(
    "FC Bayern Munchen", "SV Werder Bremen", "Borussia Dortmund",
    "VfB Stuttgart", "Borussia M'gladbach"
  ),
  matches = c(2000, 1992, 1924, 1924, 1898),
  won     = c(1206,  818,  881,  782,  763),
  lost    = c( 363,  676,  563,  673,  636)
)
dataset$win_pct  <- dataset$won  / dataset$matches * 100
dataset$loss_pct <- dataset$lost / dataset$matches * 100
dataset$team <- factor(dataset$team, levels = rev(dataset$team))

# build a ggplot2 chart
df_long <- reshape(dataset, direction = "long",
  varying = list(c("loss_pct", "win_pct")),
  v.names = "pct", timevar = "type",
  times = c("lost", "won"), idvar = "team"
)

p <- ggplot(df_long, aes(x = pct / 100, y = team)) +
  geom_point(aes(fill = type), size = 4, shape = 21) +
  scale_x_continuous(labels = scales::percent) +
  scale_y_discrete(name = NULL, guide = "none") +
  theme_minimal(base_family = "Liberation Sans", base_size = 10)

# build the flextable
ft_dat <- dataset[, c("matches", "win_pct", "loss_pct", "team")]
ft_dat$team <- as.character(ft_dat$team)

ft <- flextable(ft_dat)
ft <- border_remove(ft)
ft <- bold(ft, part = "header")
ft <- colformat_double(ft, j = c("win_pct", "loss_pct"), digits = 1, suffix = "%")
ft <- autofit(ft)

# combine with patchwork
print(
  wrap_flextable(ft, flex_body = TRUE, just = "right") +
    p + plot_layout(widths = c(1.1, 2))
)

wrap_flextable() parameters

ParameterDescriptionDefault
xA flextable object
panelTable region aligned with the plot panel: "body", "full", "rows", "cols""body"
spaceHow table dimensions influence layout: "free", "free_x", "free_y", "fixed""free"
n_row_headersNumber of leading columns treated as row headers0
flex_bodyStretch body row heights to match adjacent plot panel heightFALSE
flex_colsStretch data column widths to match adjacent plot panel widthFALSE
expandExpansion matching ggplot2::expansion(add = expand) for discrete axes0.6
justHorizontal alignment within panel: "left", "right", "center""left"
wrap_flextable() is experimental and the API may change in future versions. It requires the patchwork and gtable packages.

Direct ggplot2 addition

You can also add a flextable directly to a ggplot2 object using +. This calls wrap_flextable() automatically with default settings:
p + ft  # equivalent to p + wrap_flextable(ft)

Build docs developers (and LLMs) love