Chapter 6 officer for PowerPoint
The main functions for PowerPoint generatiion are presented below:
6.1 Add slides
You can’t add any content if there is no slide in the presentation.
To add a new slide, use the function add_slide()
. It requires 3 arguments:
- an rpptx object
- a slide layout name
- a master layout name
<- read_pptx()
my_pres <- add_slide(my_pres, layout = "Title and Content", master = "Office Theme") my_pres
The values of the “layout” and “master” arguments must match the values provided in the initial document.
Layout names and master layout names are not easily readable within
PowerPoint, but these can be read easily with the function layout_summary()
.
layout_summary(my_pres)
layout | master |
---|---|
character | character |
Title Slide | Office Theme |
Title and Content | Office Theme |
Section Header | Office Theme |
Two Content | Office Theme |
Comparison | Office Theme |
Title Only | Office Theme |
Blank | Office Theme |
n: 7 |
6.2 Add content to a slide
Content must be placed on a slide in a new shape.
ph_with()
is the unique function you should have to use to add content
to a slide. It has 3 arguments:
- the
rpptx
object, - the object to be printed
- and the location that define the placeholder where shape will be created.
<- ph_with(my_pres, value = "Hello world", location = ph_location_type(type = "title"))
my_pres <- ph_with(my_pres, value = "A footer", location = ph_location_type(type = "ftr"))
my_pres <- ph_with(my_pres, value = format(Sys.Date()), location = ph_location_type(type = "dt"))
my_pres <- ph_with(my_pres, value = "slide 1", location = ph_location_type(type = "sldNum"))
my_pres <- ph_with(my_pres, value = head(letters), location = ph_location_type(type = "body")) my_pres
6.3 Write the PowerPoint file
The (updated) Powerpoint file can be generated using the print()
function
along with the target
argument:
print(my_pres, target = "static/reports/first_example.pptx")
6.4 Content location
The function ph_with()
is expecting an argument location
that will be used
to specify the location of the new shape.
This argument must be an object created from a call to one of the ph_location*
functions (placeholder location):
ph_location_type()
: uses the location and properties of the shape identified in the layout with itstype
value.ph_location_fullsize()
: full-page location, mainly for graphicsph_location_label()
: uses the location and properties of a shape present in the layout identified by its label.ph_location_left()
: uses the location and properties of the “body” typed shape located on left of the layout named “Two Contents”.ph_location_right()
: uses the location and properties of the “body” typed shape located on right of the layout named “Two Contents”.ph_location()
: allows to freely define the location and some properties such as background color and rotation angle.ph_location_template()
: allows to freely define the location but inherits properties from a shape identified in the layout with itstype
value.
Each of these functions have an argument newlabel
that can be used to associate a label
to a new shape. It makes easy then to identify that shape and manipulate it, see Slide selection and manipulation.
6.4.1 Match with the type of shape
The following code adds text “Hello world” in a new shape.
That shape will inherit its properties from the shape that has
type body
in the layout associated with the current slide.
i.e. Title and Content
in our example.
<- read_pptx()
doc <- add_slide(doc, layout = "Title and Content")
doc <- ph_with(doc, c("Hello world", "Bonjour monde", "Blah blah blah"),
doc location = ph_location_type(type = "body") )
print(doc, target = "static/reports/ph_with_location_type.pptx")
6.4.2 Match with the label of shape
The following example will print few rows of iris
data.frame in a new shape. That shape will inherit its properties from the shape that has label Content Placeholder 2
in the layout associated with the current slide.
<- read_pptx()
mypres <- add_slide(mypres, layout = "Title and Content")
mypres layout_properties ( x = mypres, layout = "Title and Content" )
master_name | name | type | id | ph_label | ph | offx | offy | cx | cy | rotation | fld_id | fld_type |
---|---|---|---|---|---|---|---|---|---|---|---|---|
character | character | character | character | character | character | numeric | numeric | numeric | numeric | numeric | character | character |
Office Theme | Title and Content | body | 3 | Content Placeholder 2 | <p:ph idx="1"/> | 0.5 | 1.8 | 9.0 | 4.9 | |||
Office Theme | Title and Content | dt | 4 | Date Placeholder 3 | <p:ph type="dt" sz="half" idx="10"/> | 0.5 | 7.0 | 2.3 | 0.4 | {E6744CE3-0875-4B69-89C0-6F72D8139561} | datetimeFigureOut | |
Office Theme | Title and Content | ftr | 5 | Footer Placeholder 4 | <p:ph type="ftr" sz="quarter" idx="11"/> | 3.4 | 7.0 | 3.2 | 0.4 | |||
Office Theme | Title and Content | sldNum | 6 | Slide Number Placeholder 5 | <p:ph type="sldNum" sz="quarter" idx="12"/> | 7.2 | 7.0 | 2.3 | 0.4 | {8DADB20D-508E-4C6D-A9E4-257D5607B0F6} | slidenum | |
Office Theme | Title and Content | title | 2 | Title 1 | <p:ph type="title"/> | 0.5 | 0.3 | 9.0 | 1.2 | |||
n: 5 |
This is the same location that is used in the previous example
but identified with function ph_location_label()
. A title is
also added.
<- ph_with(mypres, head(iris),
mypres location = ph_location_label(
ph_label = "Content Placeholder 2") )
print(mypres, target = "static/reports/ph_with_location_1.pptx")
6.4.3 Two columns layout
This example add a new slide with layout “Two Content” and prints sets of paragraphs of text in two new shapes, one representing the left side and one representing the right side.
<- add_slide(mypres, layout = "Two Content")
mypres <- ph_with(mypres, sprintf("text item #%d", 1:6),
mypres location = ph_location_left())
<- ph_with(mypres, sprintf("text item #%d", 7:12),
mypres location = ph_location_right())
print(mypres, target = "static/reports/ph_with_location_2.pptx")
6.4.4 Free location and properties
Function ph_location()
lets you freely define the location and few properties:
<- fpar(ftext("Hello world", fp_text(color = "white", font.size = 40)))
paragraph
<- ph_location(
free_loc left = 2, top = 1.5,
width = 4.5, height = 4.5,
rotation = 45, bg = "black")
<- read_pptx()
mypres <- add_slide(mypres)
mypres <- ph_with(mypres, paragraph,
mypres location = free_loc )
print(mypres, target = "static/reports/ph_with_location_3.pptx")
6.4.5 Free location inherits properties
Function ph_location()
lets you freely define the location but inherits properties from a shape identified in the layout with its type
value.
<- read_pptx("templates/template_demo.pptx")
mypres layout_properties(mypres, layout = "Custom Slide")
master_name | name | type | id | ph_label | ph | offx | offy | cx | cy | rotation | fld_id | fld_type |
---|---|---|---|---|---|---|---|---|---|---|---|---|
character | character | character | character | character | character | numeric | numeric | numeric | numeric | numeric | character | character |
Office Theme | Custom Slide | body | 7 | message | <p:ph idx="13" hasCustomPrompt="1"/> | 0.1 | 3.1 | 9.8 | 1.2 | 326 | ||
Office Theme | Custom Slide | body | 3 | Content Placeholder 2 | <p:ph idx="1"/> | 0.5 | 1.8 | 9.0 | 4.9 | |||
Office Theme | Custom Slide | dt | 4 | Date Placeholder 3 | <p:ph type="dt" sz="half" idx="10"/> | 0.9 | 7.0 | 2.0 | 0.4 | {E6744CE3-0875-4B69-89C0-6F72D8139561} | datetimeFigureOut | |
Office Theme | Custom Slide | ftr | 5 | Footer Placeholder 4 | <p:ph type="ftr" sz="quarter" idx="11"/> | 3.4 | 7.0 | 3.2 | 0.4 | |||
Office Theme | Custom Slide | sldNum | 6 | Slide Number Placeholder 5 | <p:ph type="sldNum" sz="quarter" idx="12"/> | 7.2 | 7.0 | 2.3 | 0.4 | {8DADB20D-508E-4C6D-A9E4-257D5607B0F6} | slidenum | |
Office Theme | Custom Slide | title | 2 | Title 1 | <p:ph type="title"/> | 0.5 | 0.3 | 9.0 | 1.2 | |||
n: 6 |
<- ph_location_template(
free_loc top = 3, type = "body", id = 1,
width = 8, height = 1)
<- add_slide(mypres, layout = "Custom Slide")
mypres <- ph_with(mypres, "this is a custom message",
mypres location = free_loc )
print(mypres, target = "static/reports/ph_with_location_4.pptx")
6.4.6 Center an element with fixed size
If you want to center on a slide an element with a fixed width, for example a flextable or an image, you need to know where to position the left position.
For that, you can use function officer::slide_size
that gives the width and
the height of your slides (and the width of your fixed size element):
<- file.path( R.home("doc"), "html", "logo.jpg" )
img.file <- read_pptx()
ppt <- add_slide(ppt, layout = "Title and Content", master = "Office Theme")
ppt
<- slide_size(ppt)
s_s <- s_s$width # width of slides
s_w <- s_s$height # width of slides
s_h <- (s_w/2) - (2.78/2)
left <- (s_h/2) - (2.12/2)
top
<- ph_with(ppt, value = external_img(img.file, width = 2.78, height = 2.12),
ppt location = ph_location(left = left, top = top),
use_loc_size = FALSE)
print(ppt, target = "static/reports/ph_with_location_5.pptx")
6.4.7 A four content layout
Some users need to produce slides with more complex layouts. The example below shows the PowerPoint document used as a template and then the code needed to fill in the four placeholders in our layout.
<- read_pptx("templates/four-content.pptx")
doc <- layout_properties(doc, layout = "Four contents")
four_content_properties four_content_properties
master_name | name | type | id | ph_label | ph | offx | offy | cx | cy | rotation | fld_id | fld_type |
---|---|---|---|---|---|---|---|---|---|---|---|---|
character | character | character | character | character | character | numeric | numeric | numeric | numeric | numeric | character | character |
Office Theme | Four contents | body | 4 | Content Placeholder 4 | <p:ph sz="half" idx="2"/> | 9.9 | 0.3 | 3.0 | 7.0 | |||
Office Theme | Four contents | body | 9 | Content Placeholder 3 | <p:ph sz="half" idx="14"/> | 6.7 | 0.3 | 3.0 | 7.0 | |||
Office Theme | Four contents | body | 8 | Content Placeholder 2 | <p:ph sz="half" idx="13"/> | 3.6 | 0.3 | 3.0 | 7.0 | |||
Office Theme | Four contents | body | 3 | Content Placeholder 1 | <p:ph sz="half" idx="1"/> | 0.4 | 0.3 | 3.0 | 7.0 | |||
n: 4 |
The strategy used is to name the placeholder identifiers in the template layout and then use these identifiers to specify where to put the reporting elements. To do this, we use the function ph_location_label(ph_location_label(ph_label = 'id'))
.
<- ms_barchart(data = browser_data, x = "browser", y = "value", group = "serie") |>
chart_01 chart_settings(dir = "vertical", grouping = "clustered", gap_width = 50) |>
chart_ax_x(cross_between = "between", major_tick_mark = "out") |>
chart_ax_y(cross_between = "midCat", major_tick_mark = "in")
add_slide(doc, layout = "Four contents") |>
ph_with(value = chart_01, location = ph_location_label(ph_label = "Content Placeholder 1")) |>
ph_with(value = chart_01, location = ph_location_label(ph_label = "Content Placeholder 2")) |>
ph_with(value = chart_01, location = ph_location_label(ph_label = "Content Placeholder 3")) |>
ph_with(value = chart_01, location = ph_location_label(ph_label = "Content Placeholder 4")) |>
print(target = "static/reports/four_content_demo.pptx")
6.5 Supported contents
The following types of content are supported:
- vectors of text, numeric and factor
- formatted paragraphs made with fpar
- list of paragraphs with block_list
- unordered_list
- data.frame
- ggplot objects
- external_img
- flextable
- Microsoft charts with mschart and editable vector graphics with rvg
6.5.1 Text and vectors
<- read_pptx()
doc <- add_slide(doc, layout = "Two Content", master = "Office Theme")
doc <- ph_with(doc, value = pi, location = ph_location_type(type = "title") )
doc <- ph_with(doc, value = as.factor(letters[1:2]), location = ph_location_type(type = "ftr") )
doc <- ph_with(doc, value = c("one blah", "two blah"), location = ph_location_left() )
doc <- ph_with(doc, value = c("three blah", "four blah"), location = ph_location_right() )
doc print(doc, target = "static/reports/ph_with_vectors.pptx")
6.5.2 data.frame
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, value = head(iris),
doc location = ph_location_type(type = "body") )
print(doc, target = "static/reports/ph_with_df.pptx")
6.5.3 ggplot objects
library(ggplot2)
<- ggplot(data = iris ) +
gg_plot geom_point(
mapping = aes(Sepal.Length, Petal.Length, color = Species),
size = 3) + theme_minimal()
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, value = gg_plot,
doc location = ph_location_fullsize() )
<- ph_with(x = doc, "a ggplot example",
doc location = ph_location_type(
type = "title") )
print(doc, target = "static/reports/ph_with_gg.pptx")
6.5.4 Images
While external_img()
is considered a chunk that fits into a paragraph
for Word, it is used with PowerPoint as content on a slide.
It can also be sized with the dimensions of selected location by using use_loc_size = TRUE
in ph_with
call.
<- file.path( R.home("doc"), "html", "logo.jpg" )
img.file
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, external_img(img.file, width = 2.78, height = 2.12),
doc location = ph_location_type(type = "body"), use_loc_size = FALSE )
<- add_slide(doc)
doc <- ph_with(x = doc, external_img(img.file),
doc location = ph_location_type(type = "body"), use_loc_size = TRUE )
print(doc, target = "static/reports/ph_with_img.pptx")
6.5.5 flextable
The width and height of the flextable can not be set with a ph_location
function because a flextable is a fixed size element.
The width and height of flextable are managed by flextable not by officer.
Control of flextable sizes is documentated here.
library(flextable)
<- flextable(head(mtcars))
ft <- autofit(ft)
ft <- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, ft,
doc location = ph_location_type(type = "body") )
print(doc, target = "static/reports/flextable.pptx")
6.5.6 Editable graphics (rvg)
Package ‘rvg’ is providing a graphic device that produces Vector Graphics outputs in DrawingML format for Microsoft PowerPoint. This format let users edit the graphic elements (editable graphics) within PowerPoin and provide a very good rendering.
These raw XML outputs cannot be used as is. Functions dml()
and ph_with()
have to be used to add vector graphics in the PowerPoint document. dml()
function is a simple wrapper to mark the plot instructions as Vector Graphics
instruction.
library(rvg)
<- dml(ggobj = gg_plot)
editable_graph <- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, editable_graph,
doc location = ph_location_type(type = "body") )
print(doc, target = "static/reports/rvg.pptx")
By default, theses graphics are editable, element edition can be disabled
with option dml(..., editable = FALSE)
.
Warning, these charts are not Microsoft office charts. They do not embed the data.
6.5.7 Microsoft charts
The ‘mschart’ package allows you to create native office graphics
that can be used with ‘officer’. Function ph_with()
have to be
used as for other outputs.
library(mschart)
<- ms_barchart(data = browser_data,
my_barchart x = "browser", y = "value", group = "serie")
<- chart_settings( x = my_barchart,
my_barchart dir="vertical", grouping="clustered", gap_width = 50 )
read_pptx() |>
add_slide(layout = "Title and Content", master = "Office Theme") |>
ph_with(my_barchart, location = ph_location_type(type = "body")) |>
print(target = "static/reports/example_ppt_chart.pptx")
6.5.8 Multiple paragraphs
Multiple paragraphs are produced with function block_list()
which
is an arrangement of paragraphs of text (made with fpar()
).
The ph_with
method also accepts a level_list
option that allows the
list of paragraphs to be formatted as an unordered (bulleted) list.
# first define a block_list made of fpar ----
<- fp_text(bold = TRUE, font.size = 25)
fp_t1 <- fp_text(bold = TRUE, font.size = 25, color = "red")
fp_t2 <- fp_text(font.size = 25, color = "#006699")
fp_t3 <- fpar(ftext("hello", fp_t2), ftext(" World", fp_t3), fp_p = fp_par(text.align = "left"))
par1 <- fpar(ftext("Salut", fp_t1), ftext(" Breton", fp_t3), fp_p = fp_par(text.align = "center"))
par2
<- block_list(
bl
par1, par1, par1,
par2, par2)
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, value = bl,
doc level_list = seq_along(bl),
location = ph_location_type(type = "body") )
<- ph_with(x = doc, value = bl,
doc location = ph_location(label = "my_name",
left = 5, top = 3, width = 4, height = 4,
bg = "wheat", rotation = 90)
)
print(doc, target = "static/reports/ph_with_block_list.pptx")
6.5.9 Single paragraph
see wrapper function named
fpar()
(ablock_list
is made offpar
objects)
# first define a fpar ----
<- fpar(
fp ftext("hello", fp_text(bold = TRUE, font.size = 40)),
ftext(" world", prop = fp_text(color = "red", font.size = 40) )
)
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(x = doc, value = fp,
doc location = ph_location_type(type = "title")
)
print(doc, target = "static/reports/ph_with_fpar.pptx")
6.5.10 Unordered lists
See wrapper function named
unordered_list()
<- read_pptx()
doc
<- unordered_list(
ul level_list = c(1, 2, 2, 3, 3, 1),
str_list = c("Level1", "Level2", "Level2", "Level3", "Level3", "Level1"),
style = fp_text(color = "red", font.size = 0) )
<- add_slide(doc)
doc <- ph_with(x = doc, value = ul,
doc location = ph_location_type(type = "body") )
print(doc, target = "static/reports/ph_with_ul.pptx")
6.6 Slide selection and manipulation
add_slide()
is not the only function to let you manipulate slides,
remove_slide()
allows you to delete a slide,move_slide()
is used to move a slide in the slideshow,on_slide()
allows you to position yourself on a slide in the slideshow.
The following code is creating a slideshow made of three slides.
<- ph_location_type(type = "title")
loc <- read_pptx()
my_pres for(i in 1:3){
<- add_slide(my_pres, layout = "Title and Content")
my_pres <- ph_with(my_pres, value = paste("Slide", i), location = loc)
my_pres }
A slide can be moved with the move_slide()
function.
<- move_slide(my_pres, index = 1, to = 3)
my_pres print(my_pres, target = "static/reports/slide_manip_1.pptx")
A slide can be removed with the remove_slide()
function.
<- remove_slide(my_pres, index = 1)
my_pres print(my_pres, target = "static/reports/slide_manip_2.pptx")
A slide can be selected with the on_slide()
function. You can
then manipulate the slide, i.e. add or replace content.
<- on_slide(my_pres, index = 1)
my_pres <- ph_remove(my_pres, type = "title")
my_pres <- ph_with(my_pres, value = paste("Slide", i, "updated"), location = loc)
my_pres print(my_pres, target = "static/reports/slide_manip_3.pptx")
6.7 Slide content Manipulation
6.7.1 Remove content from a slide
Use slide_summary()
to easily identify shapes in the slide that can be removed.
<- read_pptx("static/reports/first_example.pptx")
pres slide_summary(pres)
type | id | ph_label | offx | offy | cx | cy | rotation | fld_id | fld_type | text |
---|---|---|---|---|---|---|---|---|---|---|
character | character | character | numeric | numeric | numeric | numeric | integer | character | character | character |
title | 2 | Title 1 | 0.5 | 0.3 | 9.0 | 1.2 | Hello world | |||
ftr | 3 | Footer Placeholder 4 | 3.4 | 7.0 | 3.2 | 0.4 | A footer | |||
dt | 4 | Date Placeholder 3 | 0.5 | 7.0 | 2.3 | 0.4 | 2024-02-22 | |||
sldNum | 5 | Slide Number Placeholder 5 | 7.2 | 7.0 | 2.3 | 0.4 | slide 1 | |||
body | 6 | Content Placeholder 2 | 0.5 | 1.8 | 9.0 | 4.9 | abcdef | |||
n: 5 |
In the following example, the shape corresponding to type "title"
will be
removed from the current slide:
<- ph_remove(x = pres, type = "title")
pres print(pres, target = "static/reports/remove_shape.pptx")
6.7.2 External links
ph_hyperlink()
adds a hyperlink to an existing placeholder in the current
slide. The argument href
should contain a valid URL (i.e. starting with
http(s)
).
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(doc, "Blah blah blah", location = ph_location_type(type = "body"))
doc <- ph_hyperlink(doc,
doc ph_label = "Content Placeholder 2", href = "https://cran.r-project.org")
print(doc, target = "static/reports/example_ph_hyperlink.pptx")
6.7.3 Internal links
ph_slidelink()
adds an internal link into an existing placeholder. The
argument slide_index
should contain the index of the target slide.
<- read_pptx()
doc <- add_slide(doc)
doc <- ph_with(doc, "Blah blah blah", location = ph_location_type(type = "body"))
doc <- add_slide(doc)
doc <- ph_with(doc, "placeholder target", location = ph_location_type(type = "title"))
doc <- on_slide(doc, index = 1 )
doc <- ph_slidelink(doc,
doc ph_label = "Content Placeholder 2", slide_index = 2)
print(doc, target = "static/reports/example_ph_slidelink.pptx")