简体   繁体   中英

R Officer Update the text of a shape

I am using officer to generate a weekly PowerPoint deck for my management. They have provided me with a template they wish to use. I have automated the whole process apart from one part which is causing me some difficulty i was hoping someone could help with

The first slide in the template for them is a very nice cover slide but contains a text box with the Week number the report is to address so for example Report Week 5 . I wish to change this every week i run the report. The next iteration would be Report Week 6 . The name of the text box is called TextField 26 when i press ALT+F10 in windows

I have tried numerous solutions from here , here and here

I just cant seem to reference the slide itself within the template. I have seen the response on GITHUB related to a similar question where the advice was to remove the old shape and re-add it. I would be happy to do this but again I am unable to reference the title slide.

I would really appreciate anyone's insight to this

Thank you very much for your time

To go off my comment, I wrote a function that should work. Unfortunately the RDCOMClient package does require you to be on a windows computer to work

devtools::install_github("omegahat/RDCOMClient")
library(RDCOMClient)

ReplaceTextInObject <- function(path, Find, Replace, SlideNum = NULL){
  ppApp <- COMCreate("powerpoint.application")
  #Requires absolute paths from C drive
  path <- normalizePath(c("C://Users",path), winslash = "\\")[2] 
  ppoint <- ppApp[["Presentations"]]$Open(path, WithWindow = F)
  slides <- 1:ppoint$Slides()$Count()
  #if SlideNum is NULL - loop through each slide
  if(!is.null(SlideNum)&&
     all(SlideNum%%1)==0&&
     all(SlideNum<=ppoint$Slides()$Count())){
    slides <- SlideNum
  } else{
    stop("m must be either an integer or NULL")
  } 

  for(j in slides){
    Slide <- ppoint$Slides(j)
    n <- Slide$Shapes()$Range()$Count() # Total number of shape objects on slide
    #if there are shapes with text - attempt find and replace
    if(n>0){
      for(i in 1:n){
        if(Slide$Shapes(i)$HasTextFrame()==-1&&
           Slide$Shapes(i)$TextFrame()$HasText()==-1){
             Slide$Shapes(i)$TextFrame()$TextRange()$Replace(FindWhat = Find,
                                                             ReplaceWhat = Replace)
        }
      }
    }
  }

  ppoint$Save()
  ppoint$Close()
  rm(Slide, ppoint, ppApp)
}

This function will take a slide number then look through all the objects in the slide. If the object (or shape as VBA has them listed in the documentation) can contain text and has text, then we attempt the find and replace function in that shape object.

If you knew the exact shape index, then you don't need to bother with a loop, but this will do most of the heavy lifting for you. So if the text field is really unique in your template, this should solve your problem.

I think you would have this placeholder in the template rather than in an existing slide would make things easier to manage. However, if you are using a powerpoint where the first slide contain an empty shape named "TextField 26", the officer code would be:

在此处输入图片说明

library(officer)
doc <- read_pptx("update_shape_text.pptx")
doc <- ph_add_text(doc, str = "Report Week 5", ph_label = "TextField 26") 
print(doc, "result.pptx")

Note I can't attach update_shape_text.pptx so I used a github issue so that you can get the files. https://github.com/davidgohel/flextable/issues/189

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM