PHPWord icon indicating copy to clipboard operation
PHPWord copied to clipboard

headers templates

Open mathiastm opened this issue 7 years ago • 8 comments

Hello, I'm trying to insert hearders from a Word document (.docx) into an other document. I would like to use headers from the " Hearders template document" in an other document "Template document". The "Template document" is generated by the TemplateProcessor class. Is that possible?


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

mathiastm avatar Jun 23 '17 11:06 mathiastm

I do not know the TemplateProcessor much but I think you would have to save the document, then open is with as a normal document and manipulate the headers of each section.

The following code will not run of course, but it's an idea ...

$phpWord = \PhpOffice\PhpWord\IOFactory::load("Hearders template document.docx");
$headers = $phpWord->getSections()[0]->getHeaders();

$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('Template document.docx');
$templateProcessor->saveAs('TargetDocument.docx');
$targetDocument = \PhpOffice\PhpWord\IOFactory::load("TargetDocument.docx");
$targetDocument->getSections()[0]->setHeaders(...);

troosan avatar Jun 26 '17 21:06 troosan

Hello @troosan , thank you for your answer. Actually I had the same reasoning as you, but the "Section" class does not have a "setHeaders" function...

mathiastm avatar Jun 27 '17 06:06 mathiastm

@mathiastm indeed, my mistake, you'll have to create a new header and copy values from you template header to the new one

$newHeader = $targetDocument->getSections()[0]->addHeader();

troosan avatar Jun 27 '17 18:06 troosan

@troosan do you know how to "copy" elements to an AbstractContainer?

I tryed to overwrite the AbstractContainer->addElement() function like this: I add a second parameter "$element" (element to copy) and I have changed this line :

$element = is_object($element) ? $element: $reflection->newInstanceArgs($elementArgs);
protected function addElement($elementName,$element = null)
    {
        $elementClass = __NAMESPACE__ . '\\' . $elementName;
        $this->checkValidity($elementName);

        // Get arguments
        $args = func_get_args();
        $withoutP = in_array($this->container, array('TextRun', 'Footnote', 'Endnote', 'ListItemRun', 'Field'));
        if ($withoutP && ($elementName == 'Text' || $elementName == 'PreserveText')) {
            $args[3] = null; // Remove paragraph style for texts in textrun
        }

        // Create element using reflection
        $reflection = new \ReflectionClass($elementClass);
        $elementArgs = $args;
        array_shift($elementArgs); // Shift the $elementName off the beginning of array

        /** @var \PhpOffice\PhpWord\Element\AbstractElement $element Type hint */
        $element = is_object($element) ? $element: $reflection->newInstanceArgs($elementArgs);

        // Set parent container
        $element->setParentContainer($this);
        $element->setElementIndex($this->countElements() + 1);
        $element->setElementId();

        $this->elements[] = $element;

        return $element;
    }

and my exemple code :

       $phpWord = \PhpOffice\PhpWord\IOFactory::load('Path\To\Header\Document');

        //Get main section
        $TemplateSection = $TemplatePhpWord->getSections()[0];
        // get headers
        $TemplateHeaders = $TemplateSection->getHeaders();

        // create a new document
        $outputPhpWord = new \PhpOffice\PhpWord\PhpWord();
        $outputSection = $outputPhpWord->addSection();


        foreach ($TemplateHeaders as $TemplateHeader){
            $outputHeader = $outputSection->addHeader();
            foreach ($TemplateHeader->getElements() as $TemplateElement){
                $this->copyElement($outputHeader,$TemplateElement);
            }
        }

        // Saving the document as docx file...
        $outputPhpWord->save('Output\path.docx');

    public function copyElement($container,$elementToCopy){

        $container = $container->addElement(get_class($elementToCopy),$elementToCopy);
        if(method_exists($elementToCopy,'getElements')){
            foreach ($elementToCopy->getElements() as $child){
                $this->copyElement($container,$child);
            }
        }
    }

a document is generated but it's empty....

Did I make a mistake?

mathiastm avatar Jun 28 '17 08:06 mathiastm

Would anyone have an idea please ?

mathiastm avatar Jul 04 '17 06:07 mathiastm

I'm very interested in this feature. Is there currently a way to achieve this ?

Herz3h avatar Apr 26 '19 14:04 Herz3h

any updates? very interested in any new solution

tsivickas avatar Oct 25 '20 21:10 tsivickas

any update of this issue?? Kindly share. Thanks

kamleshwebtech avatar Dec 15 '23 11:12 kamleshwebtech