Phpword: addHtml() Img tag support

Created on 25 Aug 2015  路  6Comments  路  Source: PHPOffice/PHPWord

it is possible that the addHtml function supports img tags and when find a img tag then add the image ?


Want to back this issue? Post a bounty on it! We accept bounties via Bountysource.

Most helpful comment

Edit the html.php and go to the parseNode Function. Add to the nodes array:

'img'       => array('Image',       $node,  $element,   $styles,    $data,  null,           null),

And add the parseImage Function

/**
     * Parse image node
     *
     * @param \DOMNode $node
     * @param \PhpOffice\PhpWord\Element\AbstractContainer $element
     * @param array &$styles
     * @return \PhpOffice\PhpWord\Element\TextRun
     *
    **/
    private static function parseImage($node, $element, &$styles, $data)
    {
        $style=array();
        foreach ($node->attributes as $attribute) {
            switch ($attribute->name) {
                case 'src':
                    $src=$attribute->value;
                    break;
                case 'width':
                    $width=$attribute->value;
                    $style['width']=$width;
                    break;
                case 'height':
                    $height=$attribute->value;
                    $style['height']=$height;
                    break;
                case 'style':
                    $styleattr=explode(';', $attribute->value);
                    foreach ($styleattr as $attr) {
                        if (strpos($attr, ':')) {
                            list($k, $v) = explode(':', $attr);
                            switch ($k) {
                                case 'float':
                                    if (trim($v)=='right') {
                                        $style['hPos']=\PhpOffice\PhpWord\Style\Image::POS_RIGHT;
                                        $style['hPosRelTo']=\PhpOffice\PhpWord\Style\Image::POS_RELTO_PAGE;
                                        $style['pos']=\PhpOffice\PhpWord\Style\Image::POS_RELATIVE;
                                        $style['wrap']=\PhpOffice\PhpWord\Style\Image::WRAP_TIGHT;
                                        $style['overlap']=true;
                                    }
                                    if (trim($v)=='left') {
                                        $style['hPos']=\PhpOffice\PhpWord\Style\Image::POS_LEFT;
                                        $style['hPosRelTo']=\PhpOffice\PhpWord\Style\Image::POS_RELTO_PAGE;
                                        $style['pos']=\PhpOffice\PhpWord\Style\Image::POS_RELATIVE;
                                        $style['wrap']=\PhpOffice\PhpWord\Style\Image::WRAP_TIGHT;
                                        $style['overlap']=true;
                                    }
                                    break;
                            }
                        }
                    }
                    break;
            }
        }
        $newElement = $element->addImage($src, $style);
        return $newElement;
    }

All 6 comments

I would like to see this as well.

Edit the html.php and go to the parseNode Function. Add to the nodes array:

'img'       => array('Image',       $node,  $element,   $styles,    $data,  null,           null),

And add the parseImage Function

/**
     * Parse image node
     *
     * @param \DOMNode $node
     * @param \PhpOffice\PhpWord\Element\AbstractContainer $element
     * @param array &$styles
     * @return \PhpOffice\PhpWord\Element\TextRun
     *
    **/
    private static function parseImage($node, $element, &$styles, $data)
    {
        $style=array();
        foreach ($node->attributes as $attribute) {
            switch ($attribute->name) {
                case 'src':
                    $src=$attribute->value;
                    break;
                case 'width':
                    $width=$attribute->value;
                    $style['width']=$width;
                    break;
                case 'height':
                    $height=$attribute->value;
                    $style['height']=$height;
                    break;
                case 'style':
                    $styleattr=explode(';', $attribute->value);
                    foreach ($styleattr as $attr) {
                        if (strpos($attr, ':')) {
                            list($k, $v) = explode(':', $attr);
                            switch ($k) {
                                case 'float':
                                    if (trim($v)=='right') {
                                        $style['hPos']=\PhpOffice\PhpWord\Style\Image::POS_RIGHT;
                                        $style['hPosRelTo']=\PhpOffice\PhpWord\Style\Image::POS_RELTO_PAGE;
                                        $style['pos']=\PhpOffice\PhpWord\Style\Image::POS_RELATIVE;
                                        $style['wrap']=\PhpOffice\PhpWord\Style\Image::WRAP_TIGHT;
                                        $style['overlap']=true;
                                    }
                                    if (trim($v)=='left') {
                                        $style['hPos']=\PhpOffice\PhpWord\Style\Image::POS_LEFT;
                                        $style['hPosRelTo']=\PhpOffice\PhpWord\Style\Image::POS_RELTO_PAGE;
                                        $style['pos']=\PhpOffice\PhpWord\Style\Image::POS_RELATIVE;
                                        $style['wrap']=\PhpOffice\PhpWord\Style\Image::WRAP_TIGHT;
                                        $style['overlap']=true;
                                    }
                                    break;
                            }
                        }
                    }
                    break;
            }
        }
        $newElement = $element->addImage($src, $style);
        return $newElement;
    }

@Ryuzakix3 Your solution worked for me. Thank you very much

@Ryuzakix3 Is there any way to make this work with images that are already saved in base64 format? I have a big HTML block containing various elements and the base64 images are not rendered not matter what I do.

@Ryuzakix3 super your solution

It throws an error for external images. eg. https://via.placeholder.com/150
sample code :

$html_var = '<img src=" https://via.placeholder.com/150" alt="[image]" /><br /><br />';
\PhpOffice\PhpWord\Shared\Html::addHtml($section, $html_var, false, false);

I suspected the cause in Html.php, regex is used to verify source.

 preg_match('/.+\.(\w+)$/', $src, $match);
 $src = $tmpDir . uniqid() . '.' . $match[1];

Can you help me in this. I want to write html having similar images, but it throws an error. I did small change as below. Will it be valid?

preg_match('/.+\.(\w+)$/', $src, $match);
if(!empty($match)){
    $src = $tmpDir . uniqid() . '.' . $match[1];
}else{
    $src  = $tmpDir . uniqid() . '.'.'_'. mt_rand(4000,999999);
}
Was this page helpful?
0 / 5 - 0 ratings