Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

headers templates #1085

Open
mathiastm opened this issue Jun 23, 2017 · 8 comments
Open

headers templates #1085

mathiastm opened this issue Jun 23, 2017 · 8 comments

Comments

@mathiastm
Copy link

mathiastm commented Jun 23, 2017

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.

@troosan
Copy link
Contributor

troosan commented Jun 26, 2017

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(...);

@mathiastm
Copy link
Author

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...

@troosan
Copy link
Contributor

troosan commented Jun 27, 2017

@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();

@mathiastm
Copy link
Author

mathiastm commented Jun 28, 2017

@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
Copy link
Author

Would anyone have an idea please ?

@Herz3h
Copy link

Herz3h commented Apr 26, 2019

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

@tsivickas
Copy link

any updates? very interested in any new solution

@kamleshwebtech
Copy link

any update of this issue?? Kindly share. Thanks

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Development

No branches or pull requests

5 participants