Code
sub_path <- file.path("output", "officer-examples")
dir.create(sub_path, showWarnings = FALSE, recursive = TRUE)sub_path <- file.path("output", "officer-examples")
dir.create(sub_path, showWarnings = FALSE, recursive = TRUE)To add paragraphs of text, tables, images to a Word document, you have to use one of the body_add_* functions:
body_add_blocks()body_add_break()body_add_caption()body_add_docx()body_add_fpar()body_add_gg()body_add_img()body_add_par()body_add_plot()body_add_table()body_add_toc()They all have the same output and the same first argument: the R object representing the Word document, these functions are all taking as first input the document that needs to be filled with some R content and are all returning the document, that has been augmented with the new R content(s) after the function call.
x <- body_add_par(x, "Level 1 title", style = "heading 1")
These functions are all creating one or more top level elements, either paragraphs, either tables.
To add a text paragraph, use the body_add_paragraph() function. The function requires 3 arguments, the target document, the text to be used in the new paragraph, and the paragraph style to be used.
Click to download output/officer-examples/example_par.docx.
A title is a paragraph. To add a title, use body_add_par() with the style argument set to the corresponding title style.
Click to download output/officer-examples/example_titles.docx.
A TOC (Table of Contents) is a Word computed field, table of contents is built by Word. The TOC field will collect entries using heading styles or another specified style.
Note: you have to update the fields with Word application to reflect the correct page numbers.
Use function body_add_toc() to insert a TOC inside a Word document.
doc_toc <- read_docx() |>
body_add_par("Table of Contents", style = "heading 1") |>
body_add_toc(level = 2) |>
body_add_par("Table of figures", style = "heading 1") |>
body_add_toc(style = "Image Caption") |>
body_add_par("Table of tables", style = "heading 1") |>
body_add_toc(style = "Table Caption")
print(doc_toc, target = file.path(sub_path, "example_toc.docx"))Click to download output/officer-examples/example_toc.docx.
Function body_add_gg() is also a sugar function that wrap an image generated from a ggplot into a paragraph.
library(ggplot2)
gg <- ggplot(data = iris, aes(Sepal.Length, Petal.Length)) +
geom_point()
doc_gg <- read_docx()
doc_gg <- body_add_gg(x = doc_gg, value = gg, style = "centered")The size of the Word document can be used to maximize the size of the graphic to be produced.
word_size <- docx_dim(doc_gg)
word_size$page
width height
8.263889 11.694444
$landscape
[1] FALSE
$margins
top bottom left right header footer
0.9840278 0.9840278 0.9840278 0.9840278 0.4916667 0.4916667
width <- word_size$page['width'] - word_size$margins['left'] - word_size$margins['right']
height <- word_size$page['height'] - word_size$margins['top'] - word_size$margins['bottom']
doc_gg <- body_add_gg(x = doc_gg, value = gg,
width = width, height = height,
style = "centered")
print(doc_gg, target = file.path(sub_path, "example_gg.docx"))Click to download output/officer-examples/example_gg.docx.
Page breaks are handy for formatting a Word document. They allow you to control where your document should move to the next page, such as at the end of a chapter or section.
Use function body_add_break() to add a page break in the Word document.
library(ggplot2)
library(flextable)
gg <- ggplot(data = iris, aes(Sepal.Length, Petal.Length)) +
geom_point()
ft <- flextable(head(iris, n = 10))
ft <- set_table_properties(ft, layout = "autofit")
read_docx() |>
body_add_par(value = "dataset iris", style = "heading 2") |>
body_add_flextable(value = ft ) |>
body_add_break() |>
body_add_par(value = "plot examples", style = "heading 2") |>
body_add_gg(value = gg, style = "centered") |>
print(target = file.path(sub_path, "example_break.docx"))Click to download output/officer-examples/example_break.docx.
Styles are one of the most powerful features in Microsoft Word documents. They control the appearance and formatting of content, ensuring consistency across your document and enabling features like automatic table of contents generation.
In Word, a style is a named collection of formatting properties that can be applied to:
The template file (specified via path or the default template) determines which styles are available in your document. When you use functions like body_add_par(style = "heading 2"), the style name must exist in the template.
Use styles_info() to get a data.frame listing all available styles in your document:
doc <- read_docx()
styles <- styles_info(doc)
head(styles) style_type style_id style_name base_on is_custom is_default
1 paragraph Normal Normal <NA> FALSE TRUE
2 paragraph Titre1 heading 1 Normal FALSE FALSE
3 paragraph Titre2 heading 2 Normal FALSE FALSE
4 paragraph Titre3 heading 3 Normal FALSE FALSE
5 character Policepardfaut Default Paragraph Font <NA> FALSE TRUE
6 table TableauNormal Normal Table <NA> FALSE TRUE
align keep_next line_spacing padding.bottom padding.top padding.left
1 <NA> FALSE NA <NA> <NA> <NA>
2 <NA> TRUE NA <NA> 480 <NA>
3 <NA> TRUE NA <NA> 200 <NA>
4 <NA> TRUE NA <NA> 200 <NA>
5 <NA> FALSE NA <NA> <NA> <NA>
6 <NA> FALSE NA <NA> <NA> <NA>
padding.right shading.color.par border.bottom.width border.bottom.color
1 <NA> <NA> NA <NA>
2 <NA> <NA> 0.5 auto
3 <NA> <NA> NA <NA>
4 <NA> <NA> NA <NA>
5 <NA> <NA> NA <NA>
6 <NA> <NA> NA <NA>
border.bottom.style border.top.width border.top.color border.top.style
1 <NA> NA <NA> <NA>
2 single NA <NA> <NA>
3 <NA> NA <NA> <NA>
4 <NA> NA <NA> <NA>
5 <NA> NA <NA> <NA>
6 <NA> NA <NA> <NA>
border.left.width border.left.color border.left.style border.right.width
1 NA <NA> <NA> NA
2 NA <NA> <NA> NA
3 NA <NA> <NA> NA
4 NA <NA> <NA> NA
5 NA <NA> <NA> NA
6 NA <NA> <NA> NA
border.right.color border.right.style font.size bold italic underlined color
1 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
2 <NA> <NA> 32 <NA> <NA> <NA> <NA>
3 <NA> <NA> 26 <NA> <NA> <NA> <NA>
4 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
5 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
6 <NA> <NA> <NA> <NA> <NA> <NA> <NA>
font.family vertical.align shading.color hansi.family eastasia.family
1 <NA> <NA> <NA> <NA> <NA>
2 <NA> <NA> <NA> <NA> <NA>
3 <NA> <NA> <NA> <NA> <NA>
4 <NA> <NA> <NA> <NA> <NA>
5 <NA> <NA> <NA> <NA> <NA>
6 <NA> <NA> <NA> <NA> <NA>
cs.family bold.cs font.size.cs lang.val lang.eastasia lang.bidi
1 <NA> <NA> <NA> <NA> <NA> <NA>
2 <NA> <NA> 32 <NA> <NA> <NA>
3 <NA> <NA> 26 <NA> <NA> <NA>
4 <NA> <NA> <NA> <NA> <NA> <NA>
5 <NA> <NA> <NA> <NA> <NA> <NA>
6 <NA> <NA> <NA> <NA> <NA> <NA>
The data.frame contains several important columns:
style_type: The type of style - “paragraph”, “character”, “table”, or “list”style_id: The unique identifier (mainly for internal use)style_name: The name you’ll use in R functions (e.g., “heading 1”, “Normal”)is_custom: Whether it’s a custom style (TRUE) or built-in (FALSE)is_default: Whether it’s the default style for its typeStyle names can vary depending on your Word language settings. For example: - English: “heading 1”, “Normal” - French: “Titre 1”, “Normal”
Always check with styles_info() to confirm the exact names in your template.
You can filter the styles to find specific types:
style_name is_default
1 Normal TRUE
2 heading 1 FALSE
3 heading 2 FALSE
4 heading 3 FALSE
5 centered FALSE
6 Image Caption FALSE
7 Table Caption FALSE
8 toc 1 FALSE
9 toc 2 FALSE
10 Balloon Text FALSE
When adding content to a Word document, specify the style by name:
doc <- read_docx() |>
body_add_par("This is a Heading 1", style = "heading 1") |>
body_add_par("This is normal body text.", style = "Normal") |>
body_add_par("This is a Heading 2", style = "heading 2") |>
body_add_par("More body text here.", style = "Normal")
print(doc, target = file.path(sub_path, "example_styles.docx"))Click to download output/officer-examples/example_styles.docx.
While you can create custom styles directly in Word templates, officer also provides functions to define styles programmatically. This is particularly useful for creating specialized styles for pharmaceutical reports.
Use docx_set_paragraph_style() to define a new paragraph style or modify an existing one:
# Read a template
doc <- read_docx()
# Create a custom "Table Caption" style
doc <- docx_set_paragraph_style(
doc,
base_on = "Normal", # Base on existing style
style_id = "TableCaption", # Internal ID
style_name = "Table Caption", # Name used in R
fp_p = fp_par( # Paragraph properties
text.align = "center",
padding.top = 12,
padding.bottom = 3
),
fp_t = fp_text_lite( # Text properties
font.family = "Arial",
italic = TRUE,
font.size = 11,
color = "#333333"
)
)Key parameters:
base_on: Name of an existing style to inherit fromstyle_id: Unique identifier for the style (used internally)style_name: Display name used when calling the style in Rfp_p: Paragraph formatting properties (see ?fp_par)fp_t: Text formatting properties (see ?fp_text_lite)Here’s an example creating styles for captions and graphics:
doc <- read_docx()
# Style for table captions
doc <- docx_set_paragraph_style(
doc,
base_on = "Normal",
style_id = "TableCaption",
style_name = "Table Caption",
fp_p = fp_par(text.align = "center", padding.top = 12, padding.bottom = 3),
fp_t = fp_text_lite(font.family = "Arial", italic = TRUE,
font.size = 11, color = "#333333")
)
# Style for figure captions
doc <- docx_set_paragraph_style(
doc,
base_on = "Normal",
style_id = "ImageCaption",
style_name = "Image Caption",
fp_p = fp_par(text.align = "center", padding.top = 3, padding.bottom = 12),
fp_t = fp_text_lite(font.family = "Arial", italic = TRUE,
font.size = 11, color = "#333333")
)
# Style for centered graphics
doc <- docx_set_paragraph_style(
doc,
base_on = "Normal",
style_id = "Graphic",
style_name = "Graphic",
fp_p = fp_par(text.align = "center", padding.top = 3, padding.bottom = 3)
)
# Verify the styles were created
styles_info(doc) |>
filter(style_name %in% c("Table Caption", "Image Caption", "Graphic")) |>
select(style_name, style_type, is_custom) style_name style_type is_custom
1 Image Caption paragraph TRUE
2 Table Caption paragraph TRUE
3 Graphic paragraph TRUE
Now you can use these custom styles throughout your document:
doc <- doc |>
body_add_par("Table 1: Patient Demographics", style = "Table Caption") |>
body_add_flextable(my_table) |>
body_add_par("Figure 1: Kaplan-Meier Curves", style = "Image Caption") |>
body_add_gg(my_plot, style = "Graphic")Beyond individual styles, the overall document layout (page size, margins, header and footer content, orientation) also comes from the template. You can modify these settings using:
body_set_default_section(): Set default page layout for the entire documentbody_end_block_section() add a section breakThis allows you to create documents with mixed orientations (e.g., portrait pages for text, landscape pages for wide tables) or different margins for different sections.
This will be explained in the section Chapter 6.