Templated Workflows
Source:vignettes/Creating_Templated_Office_Workflows.Rmd
Creating_Templated_Office_Workflows.Rmd
Introduction
The officer
package is used to generate all of the
underlying PowerPoint and Word documents. The purpose of
onbrand
is to provide an abstraction layer (or mapping) for
the functions in officer
in order to allow the same
reporting workflow to be used with different template documents. This
involves providing a consistent customizable method to interact with
templates as well as a form of markdown to control the formatting of
text.
If you want to use your own Office templates, we recommend you see
the Custom Office Templates Vignette. This vignette focuses on
how to construct workflows using templates. Here we will use the
internal templates embedded in onbrand
. If you want to copy
them locally you can use the following commands:
file.copy(system.file(package="onbrand", "templates", "report.pptx"), "report.pptx")
file.copy(system.file(package="onbrand", "templates", "report.docx"), "report.docx")
file.copy(system.file(package="onbrand", "templates", "report.yaml"), "report.yaml")
PowerPoint
Loading your presentation template
To create a new onbrand
object for a PowerPoint document
you need to use onbrand::read_template()
. This requires
that you supply the path to your PowerPoint document and the
yaml
mapping files as follows:
obnd = read_template(
template = file.path(system.file(package="onbrand"), "templates", "report.pptx"),
mapping = file.path(system.file(package="onbrand"), "templates", "report.yaml"))
Adding content to placeholders
The mapping file (printed at the bottom of this document) uses
descriptive names for slide masters and placeholders. Here is a snippet
from our report yaml
.
rpptx:
master: Office Theme
templates:
title_slide:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
To add content, use onbrand::report_add_slide()
. The
following will add a slide using the templated title_slide
layout. Provide the elements
argument with a list of
placeholder names - each containing a list of values for both
content
and type
. For each placeholder name
listed you need to specify the content and the type of content in its
own list:
obnd = report_add_slide(obnd,
template = "title_slide",
elements = list(
title = list( content = "Onbrand PowerPoint Example",
type = "text"),
sub_title = list( content = "Workflow Abstraction",
type = "text")))
For a detailed description of the different types of content and the
expected format see the help for the
onbrand::add_pptx_ph_content()
function. Briefly, you can
specify the following content types:
-
"text"
- a string of text (only possible when the type in the mapping file is text) -
"list"
- list of information (only possible when the type in the mapping file is list) -
"imagefile"
- string containing the path to an image file -
"ggplot"
- a ggplot object -
"table"
- list containing table content and other options -
"flextable"
- list containing flextable content and other options -
"flextable_object"
- user-defined flextable object
Lists
The previous example showed how to add text content. To add a list,
define a vector with paired content of the format
c("indent level", "content", "indent level", "content)
.
Where indent level
indicates a numeric value starting at 1.
For example, we could define the following list content:
bl = c("1", "This is first level bullet",
"2", "sub-bullet",
"3", "sub-sub-bullet",
"3", "can't have just one sub-sub-bullet",
"2", "same goes for sub-bullets",
"1", "Another first level bullet")
The list bl
can then be added to the content
value of any placeholder with list
as the type in the
mapping file:
obnd = report_add_slide(obnd,
template = "content_list",
elements = list(
title = list( content = "Adding List Content",
type = "text"),
content_body = list( content = bl,
type = "list")))
Figures
Figures can be added in two ways:
- as an image file (e.g. a png)
- as a ggplot object (preferred method)
Generally, the ggplot object is preferred as it will automatically size according to the dimensions of the placeholder. First lets create some images:
library(ggplot2)
p = ggplot() + annotate("text", x=0, y=0, label = "picture example")
imgfile = tempfile(pattern="image", fileext=".png")
ggsave(filename=imgfile, plot=p, height=5.15, width=9, units="in")
Now that the object p
contains the ggplot object and
imgfile
points to a png file containing that image, we can
add the content to our two_content_header_text
slide
template:
obnd = report_add_slide(obnd,
template = "two_content_header_text",
elements = list(
title = list(content = "Adding Images Content",
type = "text"),
content_left_header = list(content ="ggplot object",
type = "text"),
content_left = list(content = p,
type = "ggplot"),
content_right_header = list(content ="image file",
type = "text"),
content_right = list(content = imgfile,
type = "imagefile")))
Tables
Tables can be supplied in three different ways, each providing increasing level of control over the output:
-
table
- Expects a list with the tabular data and other attributes. It uses the underlying tables in PowerPoint to make the tables. -
flextable
- Expects a list similar to thetable
above, but instead of using the PowerPoint tables, the table is created using theflextable
package. -
flextable_object
- This allows you to create a flextable on your own and use it directly. The ultimate level of control.
Lets start by creating a simple data frame:
tdf = data.frame(Parameters = c("Length", "Width", "Height"),
Values = 1:3,
Units = c("m", "m", "m") )
To create a PowerPoint table, use the table
content
type. Construct a named list with a single element, table
,
containing the data frame; tab_cont = list(table = tdf)
.
You can add list elements to display header information as well. See the
help for onbrand::add_pptx_ph_content()
for details.
tab_cont = list(table = tdf)
obnd = report_add_slide(obnd,
template = "content_text",
elements = list(
title = list( content = "Tables",
type = "text"),
sub_title = list( content = "Creating PowerPoint Table",
type = "text"),
content_body = list( content = tab_cont,
type = "table")))
Sometimes you may want to have a little more control over the tabular
output. The flextable
type allows you to supply the data
and information about the flextable to be created and
onbrand
will then use them to create the flextable for
you.
tab_ft = list(table = tdf,
header_format = "md",
header_top = list(Parameters = "Name^2^",
Values = "*Value*",
Units = "**Units**"),
cwidth = 0.8,
table_autofit = TRUE,
table_theme = "theme_zebra")
Here we are specifying that we want the header format of the table to
be rendered as markdown "md"
and we are specifying that the
top header (there can be top, middle and bottom) should be overwritten
(for more on formatting with markdown see the markdown section below).
Next we specify some other details like the column width. Again
reference the help for onbrand::add_pptx_ph_content()
. It
covers the details of the list elements that can be supplied.
Alternatively, you can create a flextable object directly using the
flextable
package. There is an enormous amount of
flexibility in the flextable
package. Some of these can be
seen in the Word examples below, but you should see the documentation
for that package to get a feel for what is possible.
tab_fto = flextable(tdf)
You can then add these (flextable list: tab_ft
,
flextable object: tab_fto
) to any of the placeholders on a
slide:
obnd = report_add_slide(obnd,
template = "two_content_header_text",
elements = list(
title = list( content = "Tables",
type = "text"),
sub_title = list( content = "flextables can be created in two ways",
type = "text"),
content_left_header = list( content = 'using "flextable"',
type = "text"),
content_left = list( content = tab_ft,
type = "flextable"),
content_right_header = list( content = 'using "flextable_objecct"',
type = "text"),
content_right = list( content = tab_fto,
type = "flextable_object")))
Adding content in user-defined locations
If you want to place content in arbitrary locations on the slide you
can use the user_location
argument to
report_add_slide()
. The content and type is the same as
above. You also need to supply a start and stop point. These are x-y
coordinates as measured from the upper left point on the slide and they
define the box where the content will be inserted. They represent
fractions of the total slide width (x) and height (y):
obnd = report_add_slide(obnd,
template = "two_content_header_list",
elements = list(
title = list( content = "Combining elements, user defined locations, and formatting",
type = "text")),
user_location = list(
txt_example =
list( content = fpar(ftext("This is formatted text", fp_text(color="green", font.size=24))),
type = "text",
start = c(0, .25),
stop = c(.25,.35)),
large_figure =
list( content = p,
type = "ggplot",
start = c(.25,.25),
stop = c(.99,.99)),
flextable_obj =
list( content = tab_fto,
type = "flextable_object",
start = c(0,.75),
stop = c(.25,.95)),
small_figure =
list( content = p,
type = "ggplot",
start = c(0, .35),
stop = c(.25,.74))
)
)
Note that you can use both elements
and
user_location
together.
Saving presentations
Once you are done adding content you can save the presentation to a file:
save_report(obnd, "vignette_presentation.pptx")
Which should look something like this:
Accessing the PowerPoint mapping information
Sometimes it can be difficult to remember the template and
placeholder names from the mapping file. You and use the
onbrand::template_details
function to show this information
for the current onbrand
object.
details = template_details(obnd)
Mapping: /private/var/folders/pq/7srbf_fx3rd3k706hgxkg61r0000gp/T/RtmpbqJJ5c/temp_libpath78f636cc7423/onbrand/templates/report.yaml
Report Type: PowerPoint
title_slide (master/template)
> title (text)
> sub_title (text)
section_slide (master/template)
> title (text)
> sub_title (text)
title_only (master/template)
> title (text)
content_text (master/template)
> title (text)
> sub_title (text)
> content_body (text)
content_list (master/template)
> title (text)
> sub_title (text)
> content_body (list)
two_content_header_list (master/template)
> title (text)
> sub_title (text)
> content_left_header (text)
> content_left (list)
> content_right_header (text)
> content_right (list)
two_content_header_text (master/template)
> title (text)
> sub_title (text)
> content_left_header (text)
> content_left (text)
> content_right_header (text)
> content_right (text)
two_content_list (master/template)
> title (text)
> sub_title (text)
> content_left (list)
> content_right (list)
two_content_text (master/template)
> title (text)
> sub_title (text)
> content_left (text)
> content_right (text)
If you do not want to use the interfaces above for creating slides
but would like to use the named mapping information in a more
traditional officer
workflow you can use the function
fph
. After you’ve loaded the onbrand
object
above (obnd
) you can then pull out the placeholder label
from PowerPoint for any named placeholder in a template layout specified
in the yaml mapping file. For example if we wanted the placeholder label
for the content_left_header
in the
two_content_header_text
layout we would use the
following:
ph = fph(obnd, "two_content_header_text", "content_left_header")$pl
Word
Loading your Word template
The onbrand::read_template()
function is also used to
create a new onbrand
object for a Word report. Just as
before, you need to supply the path to your Word template and the
mapping file. This example points to files within the
onbrand
package:
obnd = read_template(
template = file.path(system.file(package="onbrand"), "templates", "report.docx"),
mapping = file.path(system.file(package="onbrand"), "templates", "report.yaml"))
Adding content
Word report content is added using the
onbrand::report_add_doc_content()
function. This expects
the user to identify the type
of content being supplied. At
a high level the following types of content can be added:
-
"break"
- page break -
"toc"
- table of contents -
"ph"
- text content to substitute for placeholders in the document -
"text"
- text supplied as either character string, markdown or the result ofofficer::fpar()
statements -
"imagefile"
- string containing the path to an image file -
"ggplot"
- a ggplot object -
"table"
- list containing table content and other options -
"flextable"
- list containing flextable content and other options -
"flextable_object"
- user-defined flextable object
Similar to adding PowerPoint content, you must also supply a list
containing the content and information about the content. Examples of
each of these will be provided in the sections below. However you should
see the help for onbrand::report_add_doc_content()
to get a
detailed explanation of the format of content
.
Table of contents
A table of contents, list of figures, or list of tables is added
using the content type "toc"
. You can supply a level and/or
an onbrand
style. If you supply a level, the TOC will be
generated down to that header level. If you supply an
onbrand
style, the TOC will include each element with that
style. So if you wish to generate separate lists of tables and figures
it is important that your onbrand
styles for those point to
different Word styles.
This will add a typical TOC:
obnd = report_add_doc_content(obnd,
type = "toc",
content = list(level=3))
While this should add the list of tables:
obnd = report_add_doc_content(obnd,
type = "toc",
content = list(style="Table_Caption"))
And this should add a list of figures:
obnd = report_add_doc_content(obnd,
type = "toc",
content = list(style="Figure_Caption"))
Note: If you try to update the TOCs and you get the following:
No table of contents entries found.
You may need to change the separator option in the yaml
mapping file from: ,
to ;
.
Text
The content type "text"
is the most straight forward way
to add content to a Word document, and the content
is a
list that has three possible elements. The only one required is the
text
element. If you just want to add text in the default
format (doc_def
in the yaml
mapping file),
then this is all you need to do:
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text="Text with no style specified will use the doc_def text format. This is a 'ph' placehoder for text: ===BODY-TEXT-EXAMPLE=== [see Placeholder text section below]"))
Styles
Alternatively you can specify any style defined in the
yaml
mapping file by adding a style
element to
the content list. This shows how to create multi-level headers:
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text ="First level header",
style = "Heading_1"))
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text ="Second level header",
style = "Heading_2"))
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text ="Third level header",
style = "Heading_3"))
Note: If you want to use table and figure caption
numbers that use section numbers (e.g. 1-1, 1-2, etc.) you may want/need
to reset the figure counter for each major section. To do this you will
need to use the fig_start_at
and tab_start_at
arguments to reset the counters for that section.
Formats
The other element you may want to control is the format of the content. In the previous examples you just needed to provide character data, but there are three possible formats you can use:
-
"text"
- character string (previous examples) -
"md"
- character string with markdown to be rendered (see the section on markdown below) -
"fpar"
-officer::fpar()
object fromofficer
(used with paragraph text) -
"ftext"
- list ofofficer::ftext()
objectsofficer
(used with captions and notes for figures and tables)
The following provide example "fpar"
and
"md"
formats
library(officer)
fpartext = fpar(
ftext("Formatted text can be created using the ", prop=NULL),
ftext("fpar ", prop=fp_text(color="green")),
ftext("command from the officer package.", prop=NULL))
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text = fpartext,
format = "fpar",
style = "Normal"))
mdtext = "Formatted text can be created using **<color:green>markdown</color>** formatting"
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text = mdtext,
format = "md",
style = "Normal"))
Figures
Similar to the PowerPoint example above we’re going to create some
figures. Both an image file (imgfile
) and a ggplot object
(p
):
p = ggplot() + annotate("text", x=0, y=0, label = "picture example")
imgfile = tempfile(pattern="image", fileext=".png")
ggsave(filename=imgfile, plot=p, height=5.15, width=9, units="in")
We can add these by specifying the appropriate content type. The content list can contain different information. Typically you would either specify the image file or ggplot object as well as a caption:
obnd = report_add_doc_content(obnd,
type = "imagefile",
content = list(image = imgfile,
caption = "This is an example of an image from a file."))
obnd = report_add_doc_content(obnd,
type = "ggplot",
content = list(image = p,
caption = "This is an example of an image from a ggplot object."))
Tables
Tables in Word are similar to the tables in PowerPoint. The table
type can be either table
, flextable
, or
flextable_object
. Lets look at this data frame to see how
to use each of these:
tdf = data.frame(Parameters = c("Length", "Width", "Height"),
Values = 1:3,
Units = c("m", "m", "m") )
To insert a native Word table, you would use the table
type and the content is just a list with an element named
table
that has the value of a dataframe. As with figures,
the content list can have an optional caption as well.
tab_cont = list(table = tdf,
caption = "Word Table.")
obnd = report_add_doc_content(obnd,
type = "table",
content = tab_cont)
Flextables can be used with the flextable
type and
information like headers, header formatting, etc can be passed along.
onbrand
will then construct the flextable for you.
tab_ft = list(table = tdf,
header_format = "md",
header_top = list(Parameters = "Name^2^",
Values = "*Value*",
Units = "**Units**"),
cwidth = 0.8,
table_autofit = TRUE,
caption = "Flextable from onbrand abstraction",
table_theme = "theme_zebra")
obnd = report_add_doc_content(obnd,
type = "flextable",
content = tab_ft)
Lastly, to have the most control over the table you can construct a flextable yourself and pass that along in the content.
tab_fto = flextable(tdf)
obnd = report_add_doc_content(obnd,
type = "flextable_object",
content = list(ft=tab_fto,
caption = "Flextable object created by the user."))
Formatting sections
Section formatting, changing the page orientation and/or the number
of columns, is controlled using the "section"
content type.
It may seem a bit counter intuitive but sections apply to the content
added since the last section type specification. So now
lets try the following:
- Add a landscape figure
- Add two column text
- Add more content in portrait orientation
To change formatting we need to close out the current section by inserting a portrait section type:
obnd = report_add_doc_content(obnd,
type = "section",
content = list(section_type ="portrait"))
Then we add the content we want in landscape mode:
obnd = report_add_doc_content(obnd,
type = "ggplot",
content = list(image = p,
height = 2.5,
width = 9,
caption = "This is a landscape figure."))
Now we tell the underlying report to apply landscape formatting to everything that has been added since the portrait section type:
obnd = report_add_doc_content(obnd,
type = "section",
content = list(section_type ="landscape",
height = 8,
width = 10))
Now we want to add the text for the two column format:
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text = paste(rep("Some two column text.", 200), collapse=" ")))
Now we insert a section indicating that we want to change the section
to multiple columns. The number of columns is inferred from the number
of elements in the widths
argument:
obnd = report_add_doc_content(obnd,
type = "section",
content = list(section_type ="columns",
widths = c(3,3)))
We can now add content but don’t forget to set the insert a portrait section at the end just before you save the document.
obnd = report_add_doc_content(obnd,
type = "text",
content = list(text = "Back to regular portrait"))
Placeholder text
When generating reporting workflows it can be helpful to have
placeholder text in the report that is populated based on the specifics
of that report. To add placeholders you can use the "ph"
content type. This content type will not appear in the yaml
file, it is unique to onbrand
. A placeholder is a unique
string of text surrounded on both sides by ===
(three
equal signs). If the placeholder is in your template document, it
may not work correctly if you type the text into Word. This is because
while a string may appear to be a contiguous in Word, it may not be so
in the underlying XML code. To ensure the string is contiguous you
should type the placeholder text into a text editor, then copy and paste
it into the Word template.
The placeholder can be in the document template itself (in the footer
or header sections) or in the text you generate and add as part of your
workflow. In this example, the text ===BODY-TEXT-EXAMPLE===
was added into the text content we added in the first step above. That
placeholder will be replaced with the text
Swaps the placeholder with this Text
.
obnd = report_add_doc_content(obnd,
type = "ph",
content = list(name = "BODY-TEXT-EXAMPLE",
value = "Swaps the placeholder with this Text",
location = "body"))
You can have the placeholders in the body as in the previous example
and also in the headers and footers of the document. Again, these will
not appear in the yaml
mapping (or abstraction layer). In
these examples the ===FOOTERLEFT===
and
===HEADERLEFT===
placeholders are found in the template
itself. There is another placeholder ===HEADERRIGHT===
which we have not used so that you can see it in the final output.
obnd = report_add_doc_content(obnd,
type = "ph",
content = list(name = "FOOTERLEFT",
value = "Text Swapped with Footer Placeholder",
location = "footer"))
obnd = report_add_doc_content(obnd,
type = "ph",
content = list(name = "HEADERLEFT",
value = "Text Swapped with Header Placeholder",
location = "header"))
Headers are applied when the document is saved and can be added at
any time to the onbrand
report object.
Formatting sections (again)
Recall up above that we were in a multi-column page format, but we wanted to return to the default portrait single column format. We added text but before we save the file we need to tell the document to apply the new section type:
obnd = report_add_doc_content(obnd,
type = "section",
content = list(section_type ="portrait"))
Note: that if you don’t alter the page format/layout from the document default, then you do not need to add any section content.
Multi-page figures and tables
Some figures and tables need to span multiple pages. If you have a
large flextable
it will do that automatically. However it
may be more desirable to have a caption on each page with the figure or
table. To accomplish this, using a figure as an example you need to
create a separate figure for each page. For each figure you will need to
provide the same key value. The first figure with that key will
be assigned a figure number and the other figures with that key will
have the same number that references the first.
obnd = report_add_doc_content(obnd,
type = "ggplot",
content = list(image = p,
notes_format = "text",
key = "ex_fig_text",
notes = "This figure shows how to use text captions _and_ notes",
caption_format = "text",
caption = "Multi-page figure (page 1)"))
obnd = report_add_doc_content(obnd,
type = "break",
content = NULL)
obnd = report_add_doc_content(obnd,
type = "ggplot",
content = list(image = p,
notes_format = "text",
key = "ex_fig_text",
notes = "This figure shows how to use text captions _and_ notes",
caption_format = "text",
caption = "Multi-page figure (page 2)"))
Cross referencing figures and tables
When figures and tables are created above each content list has an
optional key. In the example from the last section we created the key
"ex_fig_text"
. To reference in the word document you have
two options. You can construct your content using onbrand markdown. Then
you simply need to use the ref
tag:
<ref:ex_fig_text>
and the figure number will be
replaced when the document is built. You can also use the
officer::fpar()
function to construct content. Then you
would use the officer command officer::run_reference()
and
the figure key to insert the figure number.
Saving the Word report
Once you are done adding content you can save the report to a file with the `save_report()`` function as well:
save_report(obnd, "vignette_report.docx")
The output from the example above should look like this:
Accessing the Word mapping information
It can also be useful to quickly access the onbrand
style names. You can use the same onbrand::template_details
function to display the current styles available to you:
details = template_details(obnd)
Mapping: /private/var/folders/pq/7srbf_fx3rd3k706hgxkg61r0000gp/T/RtmpbqJJ5c/temp_libpath78f636cc7423/onbrand/templates/report.yaml
Report Type: Word
onbrand style (word style, style type)
--------------------------------------
Code (Code, paragraph)
Figure_Caption (graphic title, paragraph)
Heading_1 (heading 1, paragraph)
Heading_2 (heading 2, paragraph)
Heading_3 (heading 3, paragraph)
Normal (Normal, paragraph)
Notes (Notes, paragraph)
TOC (toc 1, paragraph)
Table_Caption (table title, paragraph)
Table (Table Grid, table)
As with the PowerPoint interface, you can also access the named Word
mapping directly. This is done through the fst
function.
With the onbrand
objected loaded (obnd
) you
can supply an onbrand
style name and pull out the Word
style name (wsn
) and the default font format
(dff
):
st = fst(obnd, "Heading_3")
#Word style name
wsn = st$wsn
# Default font format
dff = st$dff
Formatting with markdown
In officer
you can change formatting in text using
fpar
and as_pargraph
. There are situations
where this is less than ideal. For example if you want to take formatted
user input from a Shiny app, it may not be practical to have them supply
code this way.
To make formatting a little easier, onbrand
provides the
ability to use markdown. This can be seen above in flextable objects for
PowerPoint content and with text, captions in Word. For a list of
allowed markdown formatting see the help for
`onbrand::md_to_officer()``.
If you want to use the markdown functionality outside of
onbrand
you can use the two functions:
-
onbrand::md_to_officer
- This function will take the markdown text and convert that into strings of text containing officer commands infpar
andas_paragraph
commands. You simply need to use theeval
command to execute them. -
onbrand::md_to_oo
- A function that wraps aroundmd_to_officer
and returns theas_paragraph
result.
Using onbrand::md_to_oo
to format
First lets start with data. Here we have dimensional data listed as a mean and variance:
data = data.frame(property = c("mean", "variance"),
length = c(200, 0.13),
width = c(12, 0.05),
area = c(240, 0.11),
volume = c(1200, 0.32))
Now lets create a flextable object with a header that shows the property being reported on one line and the units on the line below:
header = list(property = c("", ""),
length = c("Length", "cm"),
width = c("Wdith", "cm"),
area = c("Area", "cm2"),
volume = c("Volume", "cm3"))
ft = flextable::flextable(data) %>%
flextable::delete_part(part = "header") %>%
flextable::add_header(values =as.list(header)) %>%
flextable::theme_zebra()
That flextable currently looks like this:
Length |
Wdith |
Area |
Volume |
|
---|---|---|---|---|
cm |
cm |
cm2 |
cm3 |
|
mean |
200.00 |
12.00 |
240.00 |
1,200.00 |
variance |
0.13 |
0.05 |
0.11 |
0.32 |
Now, lets customize some things. For example, suppose we want to use exponents on the units and represent the mean and variance with and .
First, we need to create lists with the default value for the table
labels (i.e. the header) and the table body. The markdown will create
deviations from these defaults. You can look at the help for
onbrand::md_to_oo
to get the appropriate list format. Here
we’re just pulling them out of the onbrand
object using
onbrand::fetch_md_def()
.
dft = fetch_md_def(obnd, style="Table_Labels")$md_def
dft_body = fetch_md_def(obnd, style="Table")$md_def
Now we can use the flextable::compose
function to walk
through the table and overwrite the defaults that were set when the
flextable was created:
ft = ft %>%
flextable::compose(j = "area",
part = "header",
value = c(md_to_oo("Area", dft)$oo, md_to_oo("cm^2^", dft)$oo)) %>%
flextable::compose(j = "volume",
part = "header",
value = c(md_to_oo("Volume", dft)$oo, md_to_oo("cm^3^", dft)$oo)) %>%
flextable::compose(j = "property",
i = match("mean", data$property),
part = "body",
value = c(md_to_oo("**<ff:symbol>m</ff>**", dft_body)$oo)) %>%
flextable::compose(j = "property",
i = match("variance", data$property),
part = "body",
value = c(md_to_oo("**<ff:symbol>s</ff>**^**2**^", dft_body)$oo))
Now the flextable object looks like this:
Length |
Wdith |
Area |
Volume |
|
---|---|---|---|---|
cm |
cm |
cm2 |
cm3 |
|
m |
200.00 |
12.00 |
240.00 |
1,200.00 |
s2 |
0.13 |
0.05 |
0.11 |
0.32 |
Note that the Greek symbols are not rendered correctly here but will be rendered correctly in the document.
To include the newly formatted table in the onbrand
object, you use the same method as before:
obnd = report_add_doc_content(obnd,
type = "flextable_object",
content = list(ft=tab_fto,
caption = "Flextable object with custom Markdown - created by the user."))
Accessing the officer
object directly
Sometimes you need more control over creating a report, and you may
want to use the officer commands directly. To do this you can use the
function fetch_officer_object()
to pull out the officer
object from the onbrand
object:
Now you can use any officer command you wish on the rpt
object. And when you’re done you can put the object back into the
onbrand
object using set_officer_object()
:
Mapping file
rpptx:
master: Office Theme
templates:
title_slide:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
section_slide:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
title_only:
title:
ph_label: Title 1
content_type: text
content_text:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_body:
ph_label: Content Placeholder 2
content_type: text
content_list:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_body:
ph_label: Content Placeholder 2
content_type: list
two_content_header_list:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_left_header:
ph_label: Text Placeholder 2
content_type: text
content_left:
ph_label: Content Placeholder 3
content_type: list
content_right_header:
ph_label: Text Placeholder 4
content_type: text
content_right:
ph_label: Content Placeholder 5
content_type: list
two_content_header_text:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_left_header:
ph_label: Text Placeholder 2
content_type: text
content_left:
ph_label: Content Placeholder 3
content_type: text
content_right_header:
ph_label: Text Placeholder 4
content_type: text
content_right:
ph_label: Content Placeholder 5
content_type: text
two_content_list:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_left:
ph_label: Content Placeholder 2
content_type: list
content_right:
ph_label: Content Placeholder 3
content_type: list
two_content_text:
title:
ph_label: Title 1
content_type: text
sub_title:
ph_label: Subtitle 2
content_type: text
content_left:
ph_label: Content Placeholder 2
content_type: text
content_right:
ph_label: Content Placeholder 3
content_type: text
md_def:
default:
color: black
font.size: 12
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Helvetica
vertical.align: baseline
shading.color: transparent
Table_Labels:
color: black
font.size: 12
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Helvetica
vertical.align: baseline
shading.color: transparent
post_processing: NULL
rdocx:
styles:
Normal: Normal
Notes: Notes
Code: Code
TOC: toc 1
Heading_1: heading 1
Heading_2: heading 2
Heading_3: heading 3
Table: Table Grid
Table_Caption: table title
Figure_Caption: graphic title
doc_def:
Text: Normal
Table: Table
Table_Caption: Table_Caption
Figure_Caption: Figure_Caption
Notes: Notes
formatting:
separator: ","
Table_Order:
- table
- notes
- caption
Table_Caption_Label_Pre: "Table "
Table_Caption_Label_Post: ". "
Figure_Order:
- figure
- notes
- caption
Figure_Caption_Label_Pre: "Figure "
Figure_Caption_Label_Post: ". "
Figure_Width: 6.0
Figure_Height: 5.0
Figure_Seq_Id: "Figure"
Figure_Number: |-
list(officer::run_autonum(pre_label = "",
seq_id = Caption_Seq_Id,
post_label = "",
start_at = Caption_Start_At))
Table_Seq_Id: "Table"
Table_Number: |-
list(officer::run_autonum(pre_label = "",
seq_id = Caption_Seq_Id,
post_label = "",
start_at = Caption_Start_At))
md_def:
# For each style above you need a default specification here. You will
# also need the 'default' specification, generally just a copy of Normal
default:
color: black
font.size: 12
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Cambria (Body)
vertical.align: baseline
shading.color: transparent
Table_Labels:
color: black
font.size: 12
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Helvetica
vertical.align: baseline
shading.color: transparent
Notes:
color: black
font.size: 10
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Cambria (Body)
vertical.align: baseline
shading.color: transparent
Normal:
color: black
font.size: 12
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Cambria (Body)
vertical.align: baseline
shading.color: transparent
Code:
color: black
font.size: 12
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Courier
vertical.align: baseline
shading.color: transparent
TOC:
color: black
font.size: 12
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Courier
vertical.align: baseline
shading.color: transparent
Heading_1:
color: black
font.size: 16
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Calibri (Headings)
vertical.align: baseline
shading.color: transparent
Heading_2:
color: black
font.size: 13
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Calibri (Headings)
vertical.align: baseline
shading.color: transparent
Heading_3:
color: black
font.size: 12
bold: TRUE
italic: FALSE
underlined: FALSE
font.family: Calibri (Headings)
vertical.align: baseline
shading.color: transparent
Table:
color: black
font.size: 12
bold: FALSE
italic: FALSE
underlined: FALSE
font.family: Helvetica
vertical.align: baseline
shading.color: transparent
Table_Caption:
color: black
font.size: 12
bold: TRUE
italic: TRUE
underlined: FALSE
font.family: Cambria (Body)
vertical.align: baseline
shading.color: transparent
Figure_Caption:
color: black
font.size: 12
bold: TRUE
italic: TRUE
underlined: FALSE
font.family: Cambria (Body)
vertical.align: baseline
shading.color: transparent
post_processing: NULL