Skip to content
Advertisement

How to copy styles from generated file to target file

How to copy styles and numbering from generated file to target file Generated file image. In generated file bullet points are working fine when merge this to the target file getting issue Target file. The target file was copy of tempalte and a empty file. I assumed due to no numbering.xml it does not showing the bullets as bullets if that is true how can i add numbering to the target file.

generate.php

if(!empty($newresult['header']) && !empty($result['snapshot']))
                {
                    PhpOfficePhpWordSettings::setOutputEscapingEnabled(true);
                    $phpWord = new PhpOfficePhpWordPhpWord();
                    $section = $phpWord->addSection();
                    
                    if(!empty($result['snapshot']))
                    {
                        $decoded = json_decode($result['snapshot'], true);
                        for($i = sizeof($decoded['blocks']) - 1; $i>= 0; $i--){
                            if($decoded['blocks'][$i]['text'] != '')
                                break;
                            else{
                                array_pop($decoded['blocks']);
                            }
                            
                        }
                        makeWordStrings($section, json_decode($newresult['snapshot'], true), $demographics, $decoded, $tabSize, 0);
                    } 
                    
                    $newfilename = $filename;
                    if(mysqli_num_rows($query) > 1){
                        if($result['file_part_number'] > 1)
                            $newfilename .= '_'.(strlen($result['file_part_number']-1)==1?'0'.($result['file_part_number']-1):($result['file_part_number']-1));
                        
                    }
                    $phpWord->save(WITHOUTTEMPLATE."$newfilename.docx", "Word2007");
                    
                    $templateFile  = TEMPLATES.$newresult['header'];
                    $generatedFile = WITHOUTTEMPLATE."$newfilename.docx";
                    
                    $targetFile    = $storageDirectory.($includeNoName==1?"":"$newfilename.docx");
                     
                    // copy template to target
                    copy($templateFile, $targetFile);
                    
                    
                    // open target
                    $targetZip = new ZipArchive();
                    $targetZip->open($targetFile);
                    $targetDocument = $targetZip->getFromName('word/document.xml');
                    $targetRelationsDocument = $targetZip->getFromName('word/_rels/document.xml.rels');
                    $targetCorePropsDocument = $targetZip->getFromName('docProps/core.xml');
                    $targetCustomPropsDocument = $targetZip->getFromName('docProps/custom.xml');
                    $targetContentTypesDocument = $targetZip->getFromName('[Content_Types].xml');
                    
                    $targetDom      = new DOMDocument();
                    $targetDom->loadXML($targetDocument);

                    $targetCorePropsDom = new DOMDocument();
                    $targetCorePropsDom->loadXML($targetCorePropsDocument);
                    
                    
                    $targetContentTypesDom = new DOMDocument();
                    $targetContentTypesDom->loadXML($targetContentTypesDocument);
                    
                    $targetXPath = new DOMXPath($targetDom);
                    $targetXPath->registerNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                    
                     
                    // open source
                    $sourceZip = new ZipArchive();
                    $sourceZip->open($generatedFile);
                    $sourceDocument = $sourceZip->getFromName('word/document.xml');
                    $sourceRelationsDocument = $sourceZip->getFromName('word/_rels/document.xml.rels');
                    $sourceContentTypesDocument = $sourceZip->getFromName('[Content_Types].xml');

                    $sourceDom      = new DOMDocument();
                    $sourceDom->loadXML($sourceDocument);
                    
                    $sourceRelationsDom = new DOMDocument();
                    $sourceRelationsDom->loadXML($sourceRelationsDocument);

                    $sourceContentTypes = new DOMDocument();
                    $sourceContentTypes->loadXML($sourceContentTypesDocument);

                    $sourceXPath = new DOMXPath($sourceDom);
                    $sourceXPath->registerNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                    
                    $sourceRelationsXPath = new DOMXPath($sourceRelationsDom);
                     
                    $replacementMarkerNode = $targetXPath->query('//w:p[contains(translate(normalize-space(), " ", ""),"$CONTENT$")]')[0];

                    // insert source nodes before the replacement marker
                    $sourceNodes = $sourceXPath->query('//w:document/w:body/*[not(self::w:sectPr)]');
                    
                    $relationsArr = array();
                    $startId = 700;
                    
                    $ifThereAreComments = 0;
                    
                    for ($i = 0; $i < $sourceZip->numFiles; $i++) {
                        if(strpos($sourceZip->getNameIndex($i), 'media') > 0 || strpos($sourceZip->getNameIndex($i), 'comments.xml') > 0){
                            if(strpos($sourceZip->getNameIndex($i), 'comments.xml') > 0)
                                $ifThereAreComments = 1;
                            
                            $imagefile = $sourceZip->getFromName($sourceZip->getNameIndex($i));
                            $temp = fopen(TEMPORARYFILES.substr(bin2hex(random_bytes(5)),0, 5), "w");
                            fwrite($temp, $imagefile);  
                            fseek($temp, 0);
                            
                            $targetZip -> addFile(stream_get_meta_data($temp)['uri'], $sourceZip->getNameIndex($i));
                        }
                            
                    }                   
                    
                    
                    foreach ($sourceNodes as $sourceNode) {
                        $checkifImage = $sourceNode -> getElementsByTagNameNS ("urn:schemas-microsoft-com:vml", 'imagedata');
                        foreach($checkifImage AS $t)
                        {
                            $rid = $t->getAttribute('r:id');
                            $relationsArr[$rid] = array('id'=>'rId'.$startId, 'media'=>'');
                            $t->setAttribute('r:id', $relationsArr[$rid]['id']);
                            $startId++;
                        }
                        
                        $imported = $replacementMarkerNode->ownerDocument->importNode($sourceNode, true);
                        $inserted = $replacementMarkerNode->parentNode->insertBefore($imported, $replacementMarkerNode);
                    }
                    
                    // remove $replacementMarkerNode from the target DOM
                    $replacementMarkerNode->parentNode->removeChild($replacementMarkerNode); 
                      
                    // save target
                    $targetZip->addFromString('word/document.xml', $targetDom->saveXML());
                    
                    $getSourceRelationsTree = $sourceRelationsDom -> getElementsByTagName('Relationship');
                    foreach($getSourceRelationsTree AS $t){
                        $rid = $t->getAttribute('Id');
                        if(isset($relationsArr[$rid])){
                            $relationsArr[$rid]['media'] = $t->getAttribute('Target');
                        }
                    }
                    
                    if($ifThereAreComments){
                        $targetRelationsDom = new DOMDocument();
                        $targetRelationsDom->loadXML($targetRelationsDocument);
                    
                        $parentDom = $targetRelationsDom -> getElementsByTagName('Relationships');
                        $relationsElement = $targetRelationsDom->createElement("Relationship");
                        
                        $domAttribute = $targetRelationsDom->createAttribute('Id');
                        $domAttribute->value = 'rId1000';
                        $relationsElement->appendChild($domAttribute);
                        
                        $domAttribute = $targetRelationsDom->createAttribute('Target');
                        $domAttribute->value = 'comments.xml';
                        $relationsElement->appendChild($domAttribute);
                        $domAttribute = $targetRelationsDom->createAttribute('Type');
                        $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
                        $relationsElement->appendChild($domAttribute);
                        
                        $parentDom[0]->appendChild($relationsElement);
                        
                        $targetZip->addFromString('word/_rels/document.xml.rels', $targetRelationsDom->saveXML());
                        
                        
                        $parentDom = $targetContentTypesDom -> getElementsByTagName('Types');
                        $relationsElement = $targetContentTypesDom->createElement("Override");
                        
                        $domAttribute = $targetContentTypesDom->createAttribute('PartName');
                        $domAttribute->value = '/word/comments.xml';
                        $relationsElement->appendChild($domAttribute);
                        
                        $domAttribute = $targetContentTypesDom->createAttribute('ContentType');
                        $domAttribute->value = 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml';
                        $relationsElement->appendChild($domAttribute);
                        
                        $parentDom[0]->appendChild($relationsElement);
                        
                        $targetZip->addFromString('[Content_Types].xml', $targetContentTypesDom->saveXML());                        
                        
                    }
                    
                    if(!empty($relationsArr)){
                        $targetRelationsDom = new DOMDocument();
                        $targetRelationsDom->loadXML($targetRelationsDocument);
                    
                        $parentDom = $targetRelationsDom -> getElementsByTagName('Relationships');
                        foreach($relationsArr AS $t){
                            $relationsElement = $targetRelationsDom->createElement("Relationship");
                            
                            $domAttribute = $targetRelationsDom->createAttribute('Id');
                            $domAttribute->value = $t['id'];
                            $relationsElement->appendChild($domAttribute);
                            
                            $domAttribute = $targetRelationsDom->createAttribute('Target');
                            $domAttribute->value = $t['media'];
                            $relationsElement->appendChild($domAttribute);
                            
                            $domAttribute = $targetRelationsDom->createAttribute('Type');
                            $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
                            $relationsElement->appendChild($domAttribute);
                            
                            $parentDom[0]->appendChild($relationsElement);
                        }
                        
                        $targetZip->addFromString('word/_rels/document.xml.rels', $targetRelationsDom->saveXML());
                    }
                    
                    $parentDom = $targetCorePropsDom -> getElementsByTagNameNS("http://schemas.openxmlformats.org/package/2006/metadata/core-properties", 'coreProperties');
                    $toRem = $parentDom[0]->getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", 'title')->Item(0);
                    $relationsElement = $targetCorePropsDom->createElement("dc:title", isset($demographics['{{title}}'])?$demographics['{{title}}']['value']:null);
                        
                    $parentDom[0]->appendChild($relationsElement);
                    $toRem->parentNode->removeChild($toRem);
                    
                    $toRem = $parentDom[0]->getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", 'subject')->Item(0);
                    $relationsElement = $targetCorePropsDom->createElement("dc:subject", $dict_id);
                        
                    $parentDom[0]->appendChild($relationsElement);
                    $toRem->parentNode->removeChild($toRem);
                    
                    
                    $targetZip->addFromString('docProps/core.xml', $targetCorePropsDom->saveXML());

                    
                    $targetZip->close();
}

Advertisement

Answer

When the target file copied with template file it does not had a numbering.xml file. Due to numbering.xml is not available the bullet points were converted into numbers.

The target file was written by using DOMXPATH

$sourceXPath = new DOMXPath($sourceDom);
$sourceXPath->registerNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");
                    
$sourceRelationsXPath = new DOMXPath($sourceRelationsDom);
                     
$replacementMarkerNode = $targetXPath->query('//w:p[contains(translate(normalize-space(), " ", ""),"$CONTENT$")]')[0];
                     
$sourceNodes = $sourceXPath->query('//w:document/w:body/*[not(self::w:sectPr)]');
foreach ($sourceNodes as $sourceNode) {

$imported = $replacementMarkerNode->ownerDocument->importNode($sourceNode, true);
$inserted = $replacementMarkerNode->parentNode->insertBefore($imported, $replacementMarkerNode);
                    }

Before writing the contents from source to target. Checked numbering is available or not if not then copied numbering from source file and added. It works!

$phpWord->save(PATH."$newfilename.docx", "Word2007");

$templateFile = TEMPLATES.$newresult['header'];
$generatedFile = PATH."$newfilename.docx";
$targetFile = $storageDirectory.($includeNoName==1?"":"$newfilename.docx");

copy($templateFile, $targetFile);


// open target
$targetZip = new ZipArchive();
$targetZip->open($targetFile);
$targetDocument = $targetZip->getFromName('word/document.xml');
$targetRelationsDocument = $targetZip->getFromName('word/_rels/document.xml.rels');
$targetCorePropsDocument = $targetZip->getFromName('docProps/core.xml');
$targetCustomPropsDocument = $targetZip->getFromName('docProps/custom.xml');
$targetContentTypesDocument = $targetZip->getFromName('[Content_Types].xml');
$targetDocumentnum = $targetZip->getFromName('word/numbering.xml');

$targetDom = new DOMDocument();
$targetDom->loadXML($targetDocument);


$targetCorePropsDom = new DOMDocument();
$targetCorePropsDom->loadXML($targetCorePropsDocument);



$targetContentTypesDom = new DOMDocument();
$targetContentTypesDom->loadXML($targetContentTypesDocument);

$targetXPath = new DOMXPath($targetDom);
$targetXPath->registerNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");


// open source
$sourceZip = new ZipArchive();
$sourceZip->open($generatedFile);
$sourceDocument = $sourceZip->getFromName('word/document.xml');
$sourceRelationsDocument = $sourceZip->getFromName('word/_rels/document.xml.rels');

$sourceDom = new DOMDocument();
$sourceDom->loadXML($sourceDocument);

$sourceRelationsDom = new DOMDocument();
$sourceRelationsDom->loadXML($sourceRelationsDocument);


$sourceXPath = new DOMXPath($sourceDom);
$sourceXPath->registerNamespace("w", "http://schemas.openxmlformats.org/wordprocessingml/2006/main");

$sourceRelationsXPath = new DOMXPath($sourceRelationsDom);

$replacementMarkerNode = $targetXPath->query('//w:p[contains(translate(normalize-space(), " ", ""),"$CONTENT$")]')[0];

// insert source nodes before the replacement marker
$sourceNodes = $sourceXPath->query('//w:document/w:body/*[not(self::w:sectPr)]');

$relationsArr = array();
$startId = 700;

$ifThereAreComments = 0;
for ($i = 0; $i < $sourceZip->numFiles; $i++) {
    print_r(strpos($sourceZip->getNameIndex($i), 'media'));
    if(strpos($sourceZip->getNameIndex($i), 'media') > 0 || strpos($sourceZip->getNameIndex($i), 'comments.xml') > 0
    || strpos($sourceZip->getNameIndex($i), 'numbering.xml') > 0){
    if(strpos($sourceZip->getNameIndex($i), 'comments.xml') > 0)
    $ifThereAreComments = 1;
    if(strpos($sourceZip->getNameIndex($i), 'numbering.xml') > 0)
    $ifThereAreComments = 2;

    $imagefile = $sourceZip->getFromName($sourceZip->getNameIndex($i));
    $temp = fopen(TEMPORARYFILES.substr(bin2hex(random_bytes(5)),0, 5), "w");
    fwrite($temp, $imagefile);
    fseek($temp, 0);

    $targetZip -> addFile(stream_get_meta_data($temp)['uri'], $sourceZip->getNameIndex($i));
    }

    }



    foreach ($sourceNodes as $sourceNode) {
    $checkifImage = $sourceNode -> getElementsByTagNameNS ("urn:schemas-microsoft-com:vml", 'imagedata');
    foreach($checkifImage AS $t)
    {
    $rid = $t->getAttribute('r:id');
    $relationsArr[$rid] = array('id'=>'rId'.$startId, 'media'=>'');
    $t->setAttribute('r:id', $relationsArr[$rid]['id']);
    $startId++;
    }

    $imported = $replacementMarkerNode->ownerDocument->importNode($sourceNode, true);
    $inserted = $replacementMarkerNode->parentNode->insertBefore($imported, $replacementMarkerNode);
    }

    // remove $replacementMarkerNode from the target DOM
    $replacementMarkerNode->parentNode->removeChild($replacementMarkerNode);

    // save target
    $targetZip->addFromString('word/document.xml', $targetDom->saveXML());

    $getSourceRelationsTree = $sourceRelationsDom -> getElementsByTagName('Relationship');
    foreach($getSourceRelationsTree AS $t){
    $rid = $t->getAttribute('Id');
    if(isset($relationsArr[$rid])){
    $relationsArr[$rid]['media'] = $t->getAttribute('Target');
    }
    if(isset($relationsArr[$rid])){
    $relationsArr[$rid]['numbering'] = $t->getAttribute('Target');
    }
    }

    if($ifThereAreComments){
    $targetRelationsDom = new DOMDocument();
    $targetRelationsDom->loadXML($targetRelationsDocument);

    $parentDom = $targetRelationsDom -> getElementsByTagName('Relationships');
    $relationsElement = $targetRelationsDom->createElement("Relationship");

    $domAttribute = $targetRelationsDom->createAttribute('Id');
    $domAttribute->value = 'rId1000';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Target');
    $domAttribute->value = 'comments.xml';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Type');
    $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/comments";
    $relationsElement->appendChild($domAttribute);

    if(empty($targetDocumentnum)){

    $relationsElement = $targetRelationsDom->createElement("Relationship");

    $domAttribute = $targetRelationsDom->createAttribute('Id');
    $domAttribute->value = 'rId1001';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Target');
    $domAttribute->value = 'numbering.xml';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Type');
    $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
    $relationsElement->appendChild($domAttribute);
    }

    $parentDom[0]->appendChild($relationsElement);

    $targetZip->addFromString('word/_rels/document.xml.rels', $targetRelationsDom->saveXML());


    $parentDom = $targetContentTypesDom -> getElementsByTagName('Types');
    $relationsElement = $targetContentTypesDom->createElement("Override");

    $domAttribute = $targetContentTypesDom->createAttribute('PartName');
    $domAttribute->value = '/word/comments.xml';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetContentTypesDom->createAttribute('ContentType');
    $domAttribute->value = 'application/vnd.openxmlformats-officedocument.wordprocessingml.comments+xml';
    $relationsElement->appendChild($domAttribute);

    if(empty($targetDocumentnum)){

    $domAttribute = $targetContentTypesDom->createAttribute('PartName');
    $domAttribute->value = '/word/numbering.xml';
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetContentTypesDom->createAttribute('ContentType');
    $domAttribute->value = 'application/vnd.openxmlformats-officedocument.wordprocessingml.numbering+xml';
    $relationsElement->appendChild($domAttribute);
    }

    $parentDom[0]->appendChild($relationsElement);

    $targetZip->addFromString('[Content_Types].xml', $targetContentTypesDom->saveXML());


    }

    if(!empty($relationsArr)){
    $targetRelationsDom = new DOMDocument();
    $targetRelationsDom->loadXML($targetRelationsDocument);

    $parentDom = $targetRelationsDom -> getElementsByTagName('Relationships');
    foreach($relationsArr AS $t){
    $relationsElement = $targetRelationsDom->createElement("Relationship");

    $domAttribute = $targetRelationsDom->createAttribute('Id');
    $domAttribute->value = $t['id'];
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Target');
    $domAttribute->value = $t['media'];
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Type');
    $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/image";
    $relationsElement->appendChild($domAttribute);

    $relationsElement = $targetRelationsDom->createElement("Relationship");

    $domAttribute = $targetRelationsDom->createAttribute('Id');
    $domAttribute->value = $t['id'];
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Target');
    $domAttribute->value = $t['numbering'];
    $relationsElement->appendChild($domAttribute);

    $domAttribute = $targetRelationsDom->createAttribute('Type');
    $domAttribute->value = "http://schemas.openxmlformats.org/officeDocument/2006/relationships/numbering";
    $relationsElement->appendChild($domAttribute);

    $parentDom[0]->appendChild($relationsElement);
    }

    $targetZip->addFromString('word/_rels/document.xml.rels', $targetRelationsDom->saveXML());
    }

    $parentDom = $targetCorePropsDom -> getElementsByTagNameNS("http://schemas.openxmlformats.org/package/2006/metadata/core-properties", 'coreProperties');
    $toRem = $parentDom[0]->getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", 'title')->Item(0);
    $relationsElement = $targetCorePropsDom->createElement("dc:title", isset($demographics['{{title}}'])?$demographics['{{title}}']['value']:null);

    $parentDom[0]->appendChild($relationsElement);
    $toRem->parentNode->removeChild($toRem);

    $toRem = $parentDom[0]->getElementsByTagNameNS("http://purl.org/dc/elements/1.1/", 'subject')->Item(0);
    $relationsElement = $targetCorePropsDom->createElement("dc:subject", $dict_id);

    $parentDom[0]->appendChild($relationsElement);
    $toRem->parentNode->removeChild($toRem);


    $targetZip->addFromString('docProps/core.xml', $targetCorePropsDom->saveXML());
    $targetZip->close();
Advertisement