php导出word,在已有文档后动态追加html实际项目分享

1、phpword追加html到word不支持margin的左右布局,不支持padding布局,用ol和ul布局自定义编号word文档不识别,所以当需要自定义编号时只能用p标签,p标签在word中被解析为段落;text-indent属性可使文本首行右移动,当文本太多自动换行左无法对齐,则需要计算出每行字的数量,估算一个汉字或中文符号对应两个数字或英文符号,将文本分隔为多行放入p标签右移,可以实现多行文本左对齐

计算方式如下:$text位文本内容,$length为每行展示长度,估算:一个汉字=两个数字=一个中文符号=两个英文符号,实现将多字文本按照一定长度输出为多条数组,循环右移实现对齐

function splitTextByLength($text, $length) {
    // 将字符串按字符长度分割成数组
    $chunks = mb_str_split($text, 1);

    // 计算每个字符的长度,中文符号等于两个数字的长度
    $adjustedChunks = [];
    foreach ($chunks as $chunk) {
        $adjustedChunks[] = $chunk;
        // 如果是中文符号,则再添加一个空字符
        if (mb_strlen($chunk, 'UTF-8') === 1 && preg_match('/^[\pP\pS]+$/u', $chunk)) {
            $adjustedChunks[] = '';
        }
    }

    // 去掉每一行的最后一个空格
    $adjustedChunks = rtrim(implode('', $adjustedChunks));

    // 将调整后的文本按指定长度分割
    $result = [];
    while (!empty($adjustedChunks)) {
        $line = mb_strimwidth($adjustedChunks, 0, $length, '');
        $result[] = rtrim($line);
        $adjustedChunks = mb_substr($adjustedChunks, mb_strlen($line));
    }

    return $result;
}

2、上述是第一种方案,如不用html追加,可用phpword模板处理中的克隆块、替换块、克隆行实现动态往word文档渲染内容,克隆后的内容会自动将设置的变量加上#1,#2,再用模板中的替换值动态填在数据,文档如下,具体可自行尝试

文档地址:模板处理 — PHPWord 0.16.0 文档

注:phpword中自带的替换变量不支持替换html,可在TemplateProcessor.php中加上如下代码,替换html

/**
 * @param $search
 * @param $replace
 * @param $limit
 * @return void
 */
public function setHtml($search, $replace, $limit = self::MAXIMUM_REPLACEMENTS_DEFAULT): void
{
    if (Settings::isOutputEscapingEnabled()) {
        $xmlEscaper = new Xml();
        $replace = $xmlEscaper->escape($replace);
    }

    $phpWord = new PhpWord();
    $wordFileName = tempnam(Settings::getTempDir(), 'PhpWord');
    $section = $phpWord->addSection();
    Html::addHtml($section, static::closeTags($replace), false, false);
    $phpWord->save($wordFileName);

    $zip = new ZipArchive();
    $zip->open($wordFileName);
    $docXml = $zip->getFromName('word/document.xml');
    $zip->close();
    unlink($wordFileName);

    preg_match("/<w:body>(.*?)<\/w:body>/s", $docXml, $body);
    $result = substr($body[1],0, strrpos($body[1],"<w:sectPr>"));

    if (is_array($search)) {
        foreach ($search as &$item) {
            $item = static::ensureMacroCompleted($item);
        }
        unset($item);
    } else {
        $search = static::ensureMacroCompleted($search);
    }

    $xml = simplexml_load_string($this->tempDocumentMainPart);
    $data  = $xml->xpath("//w:p[contains(.,'\$')]");
    foreach ($data as $value){
        if (strpos($value->asXml(), $search) !== false) {
            $this->tempDocumentMainPart = str_replace($value->asXml(), $result, $this->tempDocumentMainPart);
            break;
        }
    }
}
  • 23
    点赞
  • 25
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值