关于php:php解决word中在西文单词中换行属性

最近,因为公司在某些水平上要生成word文档. 在网上于是就找了PHPOffice团队出品的PHPword. 说实话,在用的过程中很不错. 然而有一些非凡的属性就不反对. 例如, 容许在西文单词中换行这个属性就没有. 上面就记录一下我整个的过程.

源码

咱们通过源代码查看, 在最终生成word的时候, 是应用的writer类的save办法. 如下

use PhpOffice\PhpWord\IOFactory;
use PhpOffice\PhpWord\PhpWord;

// 开始解决word.
$word = new PhpWord();

$writer = IOFactory::createWriter($word, 'Word2007');

$full_path = \Yii::$app->getRuntimePath() . DIRECTORY_SEPARATOR . '域名.docx';

$writer->save($full_path);

咱们找到writer类的save办法.

// vendor/phpoffice/phpword/src/PhpWord/Writer/Word2007.php
// 137行左右
foreach ($this->parts as $partName => $fileName) {
    if ($fileName != '') {
        // 这段话用了zip的形式.
        $zip->addFromString($fileName, $this->getWriterPart($partName)->write());
    }
}

在137行左右应用了addFromString办法. 这个是用zip扩大来进行生成的.zip扩大是用来创立压缩文件 . 难道word是一个zip文件? so 那咱们来试试. 将导出的文件改成.zip为后缀的压缩文件. 如下

不难发现. 咱们胜利了. 在zip外面咱们果决看到了一堆xml. 通过查找. 在zip文件中 word/document.xml这个外面会含有咱们的文字信息. 和一些排版款式. 剩下的咱们就须要做比照了. 将一个有西文单词换行的和一个没有西文单词换行的来进行比照. 如下图所示. 仅仅是多了这几列.

左侧是勾选了容许在西文单词中换行这个属性, 右侧则是没有. 剩下就是依据这个规定生成就能够了.

批改源码

通过浏览网址, 发现咱们只须要实现wordwrap就能够了. 开干. 咱们先看看其余属性的实现. 例如keepNext. 他的调用形式如下

$word = new PhpWord();
$section = $word->addSection();
$element = $section->addText('There are moments in life when you miss someone so much that you just want to pick them supercalifragilisticexpiadocious  your dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.');

$paragraph = new Paragraph();
// 减少段落标识.
$paragraph->setKeepNext(true);

$element->setParagraphStyle($paragraph);

$writer = IOFactory::createWriter($word, 'Word2007');

$writer->save(\Yii::$app->getRuntimePath() . '/1.docx');

那咱们就在Paragraph中减少setWordWrap办法. 同时咱们还发现他有hasKeepNext. 也是须要咱们减少的.

// 默认是不容许的
private $wordWrap = true;

// 是由含有容许在西文单词中换行属性
public function hasWordWrap()
{
    return $this->wordWrap;
}

// 设置容许在西文单词中换行
public function setWordWrap($value = true)
{
    $this->wordWrap = $this->setBoolVal($value, $this->wordWrap);

    return $this;
}

public function getStyleValues()
{
    $styles = array(
        'name'                => $this->getStyleName(),
        'basedOn'             => $this->getBasedOn(),
        'next'                => $this->getNext(),
        'alignment'           => $this->getAlignment(),
        'indentation'         => $this->getIndentation(),
        'spacing'             => $this->getSpace(),
        'pagination'          => array(
            'widowControl'    => $this->hasWidowControl(),
            'keepNext'        => $this->isKeepNext(),
            'keepLines'       => $this->isKeepLines(),
            'pageBreak'       => $this->hasPageBreakBefore(),
            // 新增.
            'wordWrap'        => $this->hasWordWrap(),
        ),
        'numbering'           => array(
            'style'           => $this->getNumStyle(),
            'level'           => $this->getNumLevel(),
        ),
        'tabs'                => $this->getTabs(),
        'shading'             => $this->getShading(),
        'contextualSpacing'   => $this->hasContextualSpacing(),
        'bidi'                => $this->isBidi(),
        'textAlignment'       => $this->getTextAlignment(),
        'suppressAutoHyphens' => $this->hasSuppressAutoHyphens(),
    );

    return $styles;
}

同时. 在输入的时候 咱们须要减少这个element. 所以咱们在phpoffice/phpword/src/PhpWord/Writer/Word2007/Style/Paragraph.php, 96行减少如下代码

$xmlWriter->writeElementIf($styles['pagination']['wordWrap'] !== true, 'w:wordWrap', 'w:val', '0');

最初

批改测试代码

$word = new PhpWord();
$section = $word->addSection();
$element = $section->addText('There are moments in life when you miss someone so much that you just want to pick them supercalifragilisticexpiadocious  your dreams and hug them for real! Dream what you want to dream;go where you want to go;be what you want to be,because you have only one life and one chance to do all the things you want to do.');

$paragraph = new Paragraph();
// 减少段落标识.
$paragraph->setWordWrap(false);

$element->setParagraphStyle($paragraph);

$writer = IOFactory::createWriter($word, 'Word2007');

$writer->save(\Yii::$app->getRuntimePath() . '/1.docx');

测试一下, 完满解决. 上面是我的一些参考文档

http://officeopenxml.com/WPparagraphProperties.php
https://docs.microsoft.com/zh-cn/office/vba/api/word.paragraph

【腾讯云】云产品限时秒杀,爆款1核2G云服务器,首年50元

阿里云限时活动-2核2G-5M带宽-60G SSD-1000G月流量 ,特惠价99元/年(原价1234.2元/年,可以直接买3年),速抢

本文由乐趣区整理发布,转载请注明出处,谢谢。

You may also like...

发表评论

邮箱地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据