I have an instance of a template on PHPWord. Is it possible to replace or add an image? Something like a setImageValue?
$phpWord = new \PhpOffice\PhpWord\Template('a.docx');
$phpWord->setImageValue('IMAGE_PLACEHOLDER', 'a.jpg');
$phpWord->saveAs('b.docx');
Is something like this possible?
If you want to add, remove or replace image in template.docx you can add this to your TemplateProcessor.php file, (it works for me with PhpWord 0.14.0 version):
1.
// add this in the class
protected $_rels;
protected $_types;
public function __construct($documentTemplate){
// add this line to this function
$this->_countRels=100;
}
2.
public function save()
{
//add this snippet to this function after $this->zipClass->addFromString('word/document.xml', $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);
}
}
3. Add this function too:
public function setImg( $strKey, $img){
$strKey = '${'.$strKey.'}';
$relationTmpl = '<Relationship Id="RID" Type="http://schemas.openxmlformats.org/officeDocument/2006/relationships/image" Target="media/IMG"/>';
$imgTmpl = '<w:pict><v:shape type="#_x0000_t75" style="width:WIDpx;height:HEIpx"><v:imagedata r:id="RID" o:title=""/></v:shape></w:pict>';
$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 = '<Override PartName="/word/media/'.$imgName.'" ContentType="image/EXT"/>';
$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.='<w:br/><w:t>'.$this->limpiarString($img['dataImg']).'</w:t><w:br/>';
}
$aReplace = array($imgName, $imgExt);
$toAddType .= str_replace($aSearchType, $aReplace, $typeTmpl) ;
$aReplace = array($rid, $imgName);
$toAdd .= str_replace($aSearch, $aReplace, $relationTmpl);
$this->tempDocumentMainPart=str_replace('<w:t>' . $strKey . '</w:t>', $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('</Types>', $toAddType, $this->_types) . '</Types>';
$this->_rels = str_replace('</Relationships>', $toAdd, $this->_rels) . '</Relationships>';
}
4. And this:
function limpiarString($str) {
return str_replace(
array('&', '<', '>', "\n"),
array('&', '<', '>', "\n" . '<w:br/>'),
$str
);
}
5. How to use:
//open your template
$templateProcessor = new \PhpOffice\PhpWord\TemplateProcessor('files/template.docx');
//add image to selector
$templateProcessor->setImg('selector',array('src' => 'image.jpg','swh'=>'200', 'size'=>array(0=>$width, 1=>$height));
// You can also clone row if you need
//$templateProcessor->cloneRow('NAME_IN_TEMPLATE', NUMBER_OF_TABLE_RECORDS);
$templateProcessor->cloneRow('SELECTOR', 4);
//save
header("Content-Disposition: attachment; filename='helloWord.docx'");
$templateProcessor->saveAs('php://output');
Following code is the updated version of the one from TotPeRo (thanks again for your code!), for last phpOffice (0.11) that has evolved a little
/**
* Set a new image
*
* @param string $search
* @param string $replace
*/
public function setImageValue($search, $replace)
{
// Sanity check
if (!file_exists($replace))
{
return;
}
// Delete current image
$this->zipClass->deleteName('word/media/' . $search);
// Add a new one
$this->zipClass->addFile($replace, 'word/media/' . $search);
}
Can be called with:
$document->setImageValue('image1.jpg', 'my_image.jpg');
his is pretty much untested. but this is working for me (although mine is slightly different):
add the following function to PHPWord/Template.php
:
public function save_image($id,$filepath,&$document=null) {
if(file_exists($filepath))
{
$this->_objZip->deleteName('word/media/'.$id);
$this->_objZip->addFile ($filepath,'word/media/'.$id);
//$document->setValue($id.'::width', "300px");
//$document->setValue($id.'::height', "300px");
}
}
create a document with an actual image to be used as a place holder (this solution don't allow setting the with & height of the image or multiple extensions). unzip the the documnt and check for the file name in word/media folder. use this file name as the $id for the save_image function.
you can now use:
$document->save_image('image1',$image_path,$document);
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With