最近,由于公司在某些程度上要生成word文档. 在网上于是就找了PHPOffice团队出品的PHPword. 说实话,在用的过程中很不错. 但是有一些特殊的属性就不支持. 例如, 允许在西文单词中换行这个属性就没有. 下面就记录一下我整个的过程.
源码
我们通过源代码查看, 在最终生成word的时候, 是使用的writer类的save方法. 如下
1 | use PhpOffice\PhpWord\IOFactory; |
我们找到writer类的save方法.
1 | // vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php |
在137行左右使用了addFromString方法. 这个是用zip扩展来进行生成的.zip扩展是用来创建压缩文件 . 难道word是一个zip文件? so 那我们来试试. 将导出的文件改成.zip为后缀的压缩文件. 如下
不难发现. 我们成功了. 在zip里面我们果断看到了一堆xml. 经过查找. 在zip文件中 word/document.xml这个里面会含有我们的文字信息. 和一些排版样式. 剩下的我们就需要做对比了. 将一个有西文单词换行的和一个没有西文单词换行的来进行对比. 如下图所示. 仅仅是多了这几列.
左侧是勾选了允许在西文单词中换行这个属性, 右侧则是没有. 剩下就是根据这个规则生成就可以了.
修改源码
经过阅读网址, 发现我们只需要实现wordwrap就可以了. 开干. 我们先看看其他属性的实现. 例如keepNext. 他的调用方式如下
1 | $word = new PhpWord(); |
那我们就在Paragraph中增加setWordWrap方法. 同时我们还发现他有hasKeepNext. 也是需要我们增加的.
1 | // 默认是不允许的 |
同时. 在输出的时候 我们需要增加这个element. 所以我们在phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php, 96行增加如下代码
1 | $xmlWriter->writeElementIf($styles['pagination']['wordWrap'] !== true, 'w:wordWrap', 'w:val', '0'); |
最后
修改测试代码
1 | $word = new PhpWord(); |
测试一下, 完美解决. 下面是我的一些参考文档
1 | http://officeopenxml.com/WPparagraphProperties.php |