[英]Add slides based on slide position numbers using officer package
[英]R officer package: Add slide numbers that reflect current slide position
我是 Reporters 和Officer 軟件包的狂熱用戶,目前正在嘗試過渡到Officer 的Powerpoint 工作流程。 我使用的幻燈片模板在母版中包含幻燈片編號占位符。
使用 Reporters 時,我可以使用doc <-addPageNumber( doc )
添加幻燈片編號,並且頁碼反映每張幻燈片在幻燈片中的當前位置。 我正在 Office 中尋找相同的功能,並尋找在移動幻燈片時適當更新的幻燈片編號。
當我使用ph_with_text(doc, type = "sldNum", str = "slide 1")
,我需要提供一個帶有靜態數字或文本的字符串,並且它不會根據幻燈片在幻燈片中出現的位置進行更新。 例如,如果我知道我的幻燈片將是幻燈片 2,我可以輸入str = "2"
,但是即使我將該幻燈片移動到演示文稿中幻燈片 3 的位置,幻燈片編號也會讀取為 2。
我嘗試使用str = ""
或ph_empty(type= "sldNum")
將字符串留空,但這會導致幻燈片上出現字符串“幻燈片編號”。
任何正確方向的幫助或指示將不勝感激!
完成演示后,我已使用帶有 for 循環的官員 0.3.4 成功添加了頁碼。
library(officer)
library(magrittr)
my_pres <- read_pptx() %>%
add_slide('Title Only', 'Office Theme') %>%
ph_with(value = 'Slide 2 Title', location = ph_location_type(type = "title")) %>%
add_slide('Title Only', 'Office Theme') %>%
ph_with(value = 'Slide 3 Title', location = ph_location_type(type = 'title'))
# add slide numbers starting on slide 2
n_slides <- length(my_pres)
for (i_slide in 2:n_slides) {
my_pres <- my_pres %>%
on_slide(index = i_slide) %>%
ph_with(value = i_slide, location = ph_location_type('sldNum'))
}
在與官員面臨類似問題並查看源代碼后,我想出了以下解決方案
ph_with_text_fld(doc, type = "sldNum", str = "2")
該函數的代碼如下:
library(htmltools)
library(xml2)
ph_with_text_fld <- function( x, str, type = "title", index = 1 ){
stopifnot( type %in% c("ctrTitle", "subTitle", "dt", "ftr", "sldNum", "title", "body") )
slide <- x$slide$get_slide(x$cursor)
sh_pr_df <- slide$get_xfrm(type = type, index = index)
sh_pr_df$str <- str
xml_elt <- do.call(pml_shape_str_fld, sh_pr_df)
node <- as_xml_document(xml_elt)
xml_add_child(xml_find_first(slide$get(), "//p:spTree"), node)
slide$fortify_id()
x
}
pml_shape_str_fld <- function(str, ph, offx, offy, cx, cy, ...) {
sp_pr <- sprintf("<p:spPr><a:xfrm><a:off x=\"%.0f\" y=\"%.0f\"/><a:ext cx=\"%.0f\" cy=\"%.0f\"/></a:xfrm></p:spPr>", offx, offy, cx, cy)
# sp_pr <- "<p:spPr/>"
nv_sp_pr <- "<p:nvSpPr><p:cNvPr id=\"\" name=\"\"/><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr>%s</p:nvPr></p:nvSpPr>"
nv_sp_pr <- sprintf( nv_sp_pr, ifelse(!is.na(ph), ph, "") )
paste0( pml_with_ns("p:sp"),
nv_sp_pr, sp_pr,
"<p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:fld id=\"{GUID FROM THE MASTER TEMPLATE}\" type=\"slidenum\"><a:rPr/><a:t>",
htmlEscape(str),
"</a:t></a:fld></a:p></p:txBody></p:sp>"
)
}
pml_with_ns <- function(x){
base_ns <- "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\""
sprintf("<%s %s>", x, base_ns)
}
重要的部分是
<a:fld id=\"{GUID FROM THE MASTER TEMPLATE}\" type=\"slidenum\">
其中主模板中的GUID需要替換為該字段的 Slidemaster 布局中的 GUID
我來這里是為了尋找一個比我更優雅的解決方案,但我想我至少會提供這個,因為它確實在技術上解決了你/我們的問題,只是不雅。
它可以更輕松地在幻燈片中移動而無需擔心幻燈片編號,但它也有點笨拙,即使您沒有幻燈片編號槽,您也必須小心地增加它(如在這種情況下)我的“標題”幻燈片)。
另一種方法是為自己編寫一個簡單的增量運算符 a la this question 。
presentation_name_here <- officer::read_pptx("Presentations/Template.pptx")
slide_number <- 1
# Title slide -----------------------------------------------------------
presentation_name_here <- presentation_name_here %>%
add_slide(layout = "Title Slide", master = "Office Theme") %>%
ph_with(value = "Title", location = ph_location_label(ph_label = "Title")) %>%
slide_number <- slide_number + 1
# Executive summary -----------------------------------------------------
presentation_name_here <- presentation_name_here %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with(value = "Executive summary", location = ph_location_label(ph_label = "Title")) %>%
ph_with(value = slide_number, location = ph_location_label(ph_label = "Slide Number")) %>%
slide_number <- slide_number + 1
# Dashboard ---------------------------------------------------------------
presentation_name_here <- presentation_name_here %>%
add_slide(layout = "Title and Content", master = "Office Theme") %>%
ph_with(value = "Dashboard", location = ph_location_label(ph_label = "Title")) %>%
ph_with(value = slide_number, location = ph_location_label(ph_label = "Slide Number"))
我添加了自己的代碼來根據András 的回答查找 GUID:
get.guid = function(doc, xml.file){
xml.file.path = doc$slideLayouts$.__enclos_env__$private$collection[[xml.file]]$file_name()
layout.xml = read_xml(xml.file.path)
layout.xml %>%
xml_find_first("//a:fld[@type=\"slidenum\"]") %>%
xml_attr("id")
}
ph_with_text_fld <- function( x, str, type = "title", index = 1, slide_layout_name){
stopifnot( type %in% c("ctrTitle", "subTitle", "dt", "ftr", "sldNum", "title", "body") )
slide <- x$slide$get_slide(x$cursor)
xml.file = slide$get_metadata()$layout_file %>% basename
guid = get.guid(x, xml.file)
sh_pr_df <- slide$get_xfrm(type = type, index = index)
sh_pr_df$str <- str
sh_pr_df$guid <- guid
xml_elt <- do.call(pml_shape_str_fld, sh_pr_df)
node <- as_xml_document(xml_elt)
xml_add_child(xml_find_first(slide$get(), "//p:spTree"), node)
slide$fortify_id()
x
}
pml_shape_str_fld <- function(str, ph, offx, offy, cx, cy, guid, ...) {
sp_pr <- sprintf("<p:spPr><a:xfrm><a:off x=\"%.0f\" y=\"%.0f\"/><a:ext cx=\"%.0f\" cy=\"%.0f\"/></a:xfrm></p:spPr>", offx, offy, cx, cy)
# sp_pr <- "<p:spPr/>"
nv_sp_pr <- "<p:nvSpPr><p:cNvPr id=\"\" name=\"\"/><p:cNvSpPr><a:spLocks noGrp=\"1\"/></p:cNvSpPr><p:nvPr>%s</p:nvPr></p:nvSpPr>"
nv_sp_pr <- sprintf( nv_sp_pr, ifelse(!is.na(ph), ph, "") )
paste0( pml_with_ns("p:sp"),
nv_sp_pr, sp_pr,
"<p:txBody><a:bodyPr/><a:lstStyle/><a:p><a:fld id=\"", guid, "\" type=\"slidenum\"><a:rPr/><a:t>",
htmlEscape(str),
"</a:t></a:fld></a:p></p:txBody></p:sp>"
)
}
pml_with_ns <- function(x){
base_ns <- "xmlns:a=\"http://schemas.openxmlformats.org/drawingml/2006/main\" xmlns:r=\"http://schemas.openxmlformats.org/officeDocument/2006/relationships\" xmlns:p=\"http://schemas.openxmlformats.org/presentationml/2006/main\""
sprintf("<%s %s>", x, base_ns)
}
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.