I am using officer
to manipulate a PowerPoint template in order to fill placeholders with values calculated in r
.
Is there a way to do a search-and-replace to the texts in a slide?
To my knowledge, officer
only provides the function body_replace_all_text
for Word files (docx
), but no such function for PowerPoint.
Fortunately, the slide$get()
function offers access to the XML document underlying the respective slide. The library xml2
then allows to modify these nodes. Hope this snippet will save others the frustrating search through the packages.
library("officer")
library("xml2")
# Function to replace text in all tags matching xpath
xml_replace_text = function(xml, search, replace, xpath = "//a:t") {
# Function to replace in a single text node
replace_in_node = function(node, search, replace) {
xml_text(node) = gsub(pattern = search, replacement = replace, fixed = T, x = xml_text(node))
return()
}
text_nodes = xml_find_all(xml, xpath = xpath)
lapply(text_nodes, FUN=replace_in_node, search=search, replace=replace)
return()
}
# Function to search and replace text in a slide in a pptx file
replace_in_slide = function(ppt, slide_index=1, search, replace) {
xml_replace_text(ppt$slide$get_slide(slide_index)$get(), search, replace)
return()
}
# Übersichtsseite
ppt = read_pptx("template.pptx")
replace_in_slide(ppt, 2, "%placeholder%", "Test THREE")
print(ppt, target = "example.pptx")
Note that replacing will only work if a text is actually stored in one XML tag. Avoid editing placeholder names after placing them in the text.