PHPWord
PHPWord copied to clipboard
headers templates
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.
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(...);
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 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 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?
Would anyone have an idea please ?
I'm very interested in this feature. Is there currently a way to achieve this ?
any updates? very interested in any new solution
any update of this issue?? Kindly share. Thanks