phpword使用html保存为word,图片width解析不了,全局样式导入不了
php框架symfony5.4
phpoffice/phpword 包版本 ^0.18.3
有一个非我负责的项目需要做文章批量导出为word功能,调研后决定采用phpword,使用过程中碰到以下问题:
1、全局样式无法导入
phpword addHTML方法的$html字段只支持以下样式
1 <!DOCTYPE html> 2 <html> 3 <head> 4 <meta http-equiv="Content-Type" content="text/html; charset=utf-8" /> 5 </head> 6 <body> 7 <p style='font-size: 16px;color: #999999;'>test</p> 8 <img src="/image/20210226-1614324791820472.jpg" alt="1.jpg" style="width: 550; text-indent: 0; margin-bottom: 0px; margin-left: -1em;"> 9 </body></html>
但是如果是下面这种全局样式,p标签下的内容的就不会生效
<!DOCTYPE html> <html> <head> <meta http-equiv="Content-Type" content="text/html; charset=utf-" /> </head> <body> <style> p {font-size:18px;text-indent:36px;line-height:2.2;margin-bottom:30px;} </style> <p>test</p> <img src="/image/20210226-1614324791820472.jpg" alt="1.jpg" style="width: 550; text-indent: 0; margin-bottom: 0px; margin-left: -1em;"> </body></html>
想到的解决方法是使用 ‘tijsverkoyen/css-to-inline-styles‘ 这个包来使全局样式转换为行内样式,然后再进行导出。
2、图片width解析不了
在导出word后发现图片宽度普遍比较宽,需要设置图片的宽度为500px,然而用以下方式修改并不会生效
<img src="/image/20210226-1614324791820472.jpg" alt="1.jpg" style="width: 550; text-indent: 0; margin-bottom: 0px; margin-left: -1em;">
如果直接这样就可以生效
<img src="/image/20210226-1614324791820472.jpg" width="550">
查看phpword的包发现该文件下的 788行 parseImage 方法style样式下只解析了float,没解析width,所有2个解决方案:
1用第一种解决方案,2 829行新增以下代码(描红区域)
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_MARGIN; // inner section area $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_MARGIN; // inner section area $style['pos'] = \PhpOffice\PhpWord\Style\Image::POS_RELATIVE; $style['wrap'] = \PhpOffice\PhpWord\Style\Image::WRAP_TIGHT; $style['overlap'] = true; } break; case 'width': $style['width'] = $v; $style['unit'] = \PhpOffice\PhpWord\Style\Image::UNIT_PX; break; } } } break;