diff --git a/docs/templates-processing.rst b/docs/templates-processing.rst index af03b24586..5e778ed810 100644 --- a/docs/templates-processing.rst +++ b/docs/templates-processing.rst @@ -23,3 +23,12 @@ multirow from a single row in a template by using ``TemplateProcessor::cloneRow` See ``Sample_23_TemplateBlock.php`` for example on how to clone a block of text using ``TemplateProcessor::cloneBlock`` and delete a block of text using ``TemplateProcessor::deleteBlock``. + +You can also replace text block template with a picture. + +Example: + +.. code-block:: php + + $templateProcessor = new TemplateProcessor('Template.docx'); + $templateProcessor->setImg('LOGO',array('src' => '../assets/picture.png','size'=>array(0=>300, 1=>150))); \ No newline at end of file diff --git a/src/PhpWord/TemplateProcessor.php b/src/PhpWord/TemplateProcessor.php index 7a5eaf55bb..2caa9c7264 100644 --- a/src/PhpWord/TemplateProcessor.php +++ b/src/PhpWord/TemplateProcessor.php @@ -62,6 +62,9 @@ class TemplateProcessor */ protected $tempDocumentFooters = array(); + protected $_rels; + protected $_types; + /** * @since 0.12.0 Throws CreateTemporaryFileException and CopyFileException instead of Exception * @@ -101,6 +104,7 @@ public function __construct($documentTemplate) $index++; } $this->tempDocumentMainPart = $this->fixBrokenMacros($this->zipClass->getFromName($this->getMainPartName())); + $this->_countRels=100; } /** @@ -193,7 +197,7 @@ protected static function ensureMacroCompleted($macro) */ protected static function ensureUtf8Encoded($subject) { - if (!Text::isUTF8($subject)) { + if (!StringUtils::isValidUtf8($subject)) { $subject = utf8_encode($subject); } @@ -323,7 +327,7 @@ public function cloneBlock($blockname, $clones = 1, $replace = true) { $xmlBlock = null; preg_match( - '/(<\?xml.*)(\${' . $blockname . '}<\/w:.*?p>)(.*)()/is', + '/(<\?xml.*)(\${' . $blockname . '}<\/w:.*?p>)(.*)()/is', $this->tempDocumentMainPart, $matches ); @@ -394,6 +398,12 @@ public function save() } $this->zipClass->addFromString($this->getMainPartName(), $this->tempDocumentMainPart); + if($this->_rels!=""){ + $this->zipClass->addFromString('word/_rels/document.xml.rels', $this->_rels); + } + if($this->_types!=""){ + $this->zipClass->addFromString('[Content_Types].xml', $this->_types); + } foreach ($this->tempDocumentFooters as $index => $xml) { $this->zipClass->addFromString($this->getFooterName($index), $xml); @@ -406,6 +416,100 @@ public function save() return $this->tempDocumentFilename; } + + /** + * Replace a block with a picture. + * Code from https://github.com/PHPOffice/PHPWord/issues/708 + * + * @param string $strKey the string to replace + * @param array $img the informations about the image. Associative array : 'src' => 'path.png', 'size'=>array(0=>width, 1=>height) + * + * @return string + */ + public function setImg( $strKey, $img){ + $strKey = '${'.$strKey.'}'; + $relationTmpl = ''; + + $imgTmpl = ''; + + $toAdd = $toAddImg = $toAddType = ''; + $aSearch = array('RID', 'IMG'); + $aSearchType = array('IMG', 'EXT'); + $countrels=$this->_countRels++; + //I'm work for jpg files, if you are working with other images types -> Write conditions here + $imgExt = 'jpg'; + $imgName = 'img' . $countrels . '.' . $imgExt; + + $this->zipClass->deleteName('word/media/' . $imgName); + $this->zipClass->addFile($img['src'], 'word/media/' . $imgName); + + $typeTmpl = ''; + + + $rid = 'rId' . $countrels; + $countrels++; + list($w,$h) = getimagesize($img['src']); + + if(isset($img['swh'])) //Image proportionally larger side + { + if($w<=$h) + { + $ht=(int)$img['swh']; + $ot=$w/$h; + $wh=(int)$img['swh']*$ot; + $wh=round($wh); + } + if($w>=$h) + { + $wh=(int)$img['swh']; + $ot=$h/$w; + $ht=(int)$img['swh']*$ot; + $ht=round($ht); + } + $w=$wh; + $h=$ht; + } + + if(isset($img['size'])) + { + $w = $img['size'][0]; + $h = $img['size'][1]; + } + + + $toAddImg .= str_replace(array('RID', 'WID', 'HEI'), array($rid, $w, $h), $imgTmpl) ; + if(isset($img['dataImg'])) + { + $toAddImg.=''.$this->limpiarString($img['dataImg']).''; + } + + $aReplace = array($imgName, $imgExt); + $toAddType .= str_replace($aSearchType, $aReplace, $typeTmpl) ; + + $aReplace = array($rid, $imgName); + $toAdd .= str_replace($aSearch, $aReplace, $relationTmpl); + + + $this->tempDocumentMainPart=str_replace('' . $strKey . '', $toAddImg, $this->tempDocumentMainPart); + //print $this->tempDocumentMainPart; + + if($this->_rels=="") + { + $this->_rels=$this->zipClass->getFromName('word/_rels/document.xml.rels'); + $this->_types=$this->zipClass->getFromName('[Content_Types].xml'); + } + + $this->_types = str_replace('', $toAddType, $this->_types) . ''; + $this->_rels = str_replace('', $toAdd, $this->_rels) . ''; + } + + function limpiarString($str) { + return str_replace( + array('&', '<', '>', "\n"), + array('&', '<', '>', "\n" . ''), + $str + ); + } /** * Saves the result document to the user defined file.