Chapter 12 FAQ

12.1 Is it possible to edit or create Word styles from R

Yes. Use officer::docx_set_paragraph_style() to add or update a paragraph style, and officer::docx_set_character_style() for a character (run) style. Both let you set font, size, colour, bold/italic, alignment and the usual paragraph/run properties on the target docx, so the new style is then available like any built-in one.

12.2 Do you want to update the fields in this document?

When you open a document produced with officer/officedown, Word may ask:

This document contains fields that may refer to other files. Do you want to update the fields in this document?

Click “Yes”.

Calculated fields (table of contents, list of figures/tables, page and line numbers, cross-references, etc.) are extremely useful but they are not values, they are formulas that Word evaluates. R writes the field definitions into the docx, but only Word itself can compute them. Until the fields are updated, you see placeholders (often 0 or Error! Reference source not found.) instead of the real values.

Word asks before updating because some field types can pull external data, which is a security concern; that’s why it’s a prompt and not automatic.

If you need the fields resolved without opening Word manually (for example in a CI pipeline or before sending the file to a non-Word user), use doconv::docx_update().

12.3 My document shows “Error! Reference source not found.”

You opened your generated docx and a cross-reference (or a page number, table of contents entry, etc.) displays as Error! Reference source not found. instead of the expected value.

This is the same root cause as the update-fields prompt: the cross-reference is a Word field that has never been evaluated. Either open the document in Word and answer Yes to the update prompt, press Ctrl+A then F9 to force-update all fields, or run doconv::docx_update() to update the fields without opening Word.

If the message persists after updating, the bookmark/anchor referenced by the field really is missing from the document, check the bookmark name on the R side (officer::body_bookmark(), captions, etc.).

12.4 Add a bullet or numbered list on a Word document with officer

Bulleted and numbered lists are supported natively since officer 0.7.4. Build the items with list_item(), assemble them with block_list_items() (pass list_type = "bullet" or "decimal"), and insert the result with body_add_list() in Word or ph_with() in PowerPoint. The Lists section of the Word chapter covers the workflow in detail, including multi-level nesting and rich text inside items.

Reusing a paragraph style that carries a bullet (as older versions of the book suggested) still works, but is no longer the recommended approach.

12.5 How to keep images original height/width ratio in R Markdown?

This question comes up regularly from users working with R Markdown (or officedown) documents. They want to insert pre-existing image files (not plots generated by R) into the rendered Word output, keep the original height/width ratio, and still get captions and cross-references.

The answer is to insert the image with the standard Markdown image syntax rather than going through an R chunk. This applies to all Markdown formats, not just officedown:

![caption](path/to/image)

Captions are simple paragraphs. Use officer::block_caption() or create your caption by hand in pure markdown.

With pandoc, you can associate a paragraph style with some text, if the style is associated with a auto-number, you have a caption style! That’s out of the scope of officedown but documented here: office-documents-generation.html#usage-with-rmarkdown.

12.6 How to create a report within Shiny application

This is a minimal example that shows how to use officer from a shiny application:

library(shiny)
library(officer)
library(ggplot2)

ui <- fluidPage(
  # Application title
  titlePanel("Old Faithful Geyser Data"),
  sidebarLayout(
    sidebarPanel(
      sliderInput("bins", "Number of bins:", min = 1, max = 50, value = 30),
      downloadButton("downloadReport", "Download report")
    ),
    mainPanel(
      plotOutput("distPlot")
    )
  )
)

server <- function(input, output) {
  my_plot <- reactive({
    ggplot(faithful, aes(eruptions)) +
      geom_histogram(bins = input$bins)
  })
  output$distPlot <- renderPlot({
    my_plot()
  })
  output$downloadReport <- downloadHandler(
    filename = function() {
      paste("report-", Sys.Date(), ".docx", sep = "")
    },
    content = function(file) {
      doc <- read_docx()
      doc <- body_add_gg(doc, value = my_plot())
      print(doc, target = file)
    }
  )
}

shinyApp(ui = ui, server = server)