Skip to content

How to use bookmarks in PhpWord #2040

Open
@xTwisten

Description

@xTwisten

I searched but i didn't find anything about bookmarks.

I created template on word and insert some bookmarks, but i don't know how i can replace the bookmarks by string in php.

I tried :

$doc = new TemplateProcessor("template.docx");
$doc->setValue('phone', "1234567890");
$doc->saveAs("output.docx");

AND

$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor("template.docx");
$templateProcessor->replaceBookmark('phone', '1234567890');
$templateProcessor->saveAs('output\output_'.date("Y-m-d_H-i-s").'.docx');

I add that in the "TemplateProcessor.php" file.

public function replaceBookmark($search, $replace)
   {
       if (is_array($replace)) {
           foreach ($replace as &$item) {
               $item = self::ensureUtf8Encoded($item);
           }
       } else {
           $replace = self::ensureUtf8Encoded($replace);
       }

       if (Settings::isOutputEscapingEnabled()) {
           $xmlEscaper = new Xml();
           $replace = $xmlEscaper->escape($replace);
       }

       foreach ($this->tempDocumentHeaders as $index => $xml) {
           $xml = $this->setBookmarkForPart($search, $replace, $xml);
       }
       $this->tempDocumentMainPart = $this->setBookmarkForPart($search, $replace, $this->tempDocumentMainPart);
       foreach ($this->tempDocumentFooters as $index => $xml) {
           $xml = $this->setBookmarkForPart($search, $replace, $xml);
       }

   }
   protected function setBookmarkForPart($search, $replace, $documentPartXML)
   {
       $regExpEscaper = new RegExp();
       $pattern = '~<w:bookmarkStart\s+w:id="(\d*)"\s+w:name="'.$search.'"\s*\/>()~mU';
       $searchstatus = preg_match($pattern, $documentPartXML, $matches, PREG_OFFSET_CAPTURE);
       if($searchstatus){
           $startbookmark = $matches[2][1];
           $pattern = '~(<w:bookmarkEnd\s+w:id="'.$matches[1][0].'"\s*\/>)~mU';
           $searchstatus = preg_match($pattern, $documentPartXML, $matches, PREG_OFFSET_CAPTURE, $startbookmark);
           if($searchstatus){
               $endbookmark = $matches[1][1];
               $count = 0;
               $startpos = $startbookmark;
               $pattern = '~(<w:t[\s\S]*>)([\s\S]*)(<\/w:t>)~mU';
               do{
                   $searchstatus = preg_match($pattern, $documentPartXML, $matches, PREG_OFFSET_CAPTURE, $startpos);
                   if($searchstatus){
                       if($count == 0){
                           $startpos = $matches[2][1];
                           $endpos = $matches[3][1];
                       }else{
                           $startpos = $matches[1][1];
                           $endpos = $matches[3][1] + 6;
                       }
                       if($endpos > $endbookmark){
                           break;
                       }

                       $documentPartXML = substr($documentPartXML, 0, $startpos) . ($count == 0 ? $replace : '') . substr($documentPartXML, $endpos);
                       $endbookmark = $endbookmark - ($endpos - $startpos);

                       $count ++;
                   }

               }while($searchstatus);

           }
       }

       return $documentPartXML;
   }

Sorry for my english i'm french.

Thanks you,

Have a nice day

Metadata

Metadata

Assignees

No one assigned

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions