You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

PhpSpreadsheet导入HTML表格时如何保留单元格内的富文本格式

PhpSpreadsheet转换HTML表格丢失行内格式的解决方法

问题成因

  • 官方内置的Html读取器默认仅提取HTML标签包裹的纯文本,完全忽略行内标签携带的样式属性,<strong>加粗、<em>斜体这类行内格式会被直接丢弃
  • HTML解析逻辑默认折叠标签前后的连续空白,读取器处理时会直接清除这类空白,最终出现Hi mi name is <strong>SAM</strong> and i feel good被拼接为Hi mi name isSAMand i feel good的异常

实现思路

原生Html读取器本身不支持单元格内混合格式的解析,需要手动拆分HTML单元格的文本片段,调用PhpSpreadsheet的RichText类给不同片段绑定对应的字体样式,最终实现和HTML一致的行内格式效果。

核心实现步骤

  1. 空白预处理
    对所有单元格内的HTML内容做正则替换,把标签前后的连续换行、缩进等空白统一替换为单个普通空格,避免被解析器折叠清除,保证文本的间隔和原始HTML一致
  2. HTML结构解析
    用内置的DOMDocument加载单元格内容,遍历所有子节点,区分纯文本节点和带格式的元素节点
  3. 富文本组装
    • 纯文本节点直接写入RichText对象,使用默认字体样式
    • 带格式的节点根据标签类型(<strong>/<em>等)生成对应的TextRun实例,给实例绑定加粗、斜体等字体属性
  4. 常规输出
    把组装完成的RichText对象赋值给对应单元格,后续走正常的Excel文件输出逻辑即可

可参考的核心代码片段

require 'vendor/autoload.php';

use PhpOffice\PhpSpreadsheet\Spreadsheet;
use PhpOffice\PhpSpreadsheet\RichText\RichText;

$spreadsheet = new Spreadsheet();
$worksheet = $spreadsheet->getActiveSheet();

// 示例待处理的TD原始内容
$tdContent = "
   Hi mi name is <strong>SAM</strong> and i feel good
";

// 预处理空白,避免被折叠
$tdContent = preg_replace('/\s*</', ' <', $tdContent);
$tdContent = preg_replace('/>\s*/', '> ', $tdContent);
$tdContent = trim(preg_replace('/\s+/', ' ', $tdContent));

// 解析DOM结构
libxml_use_internal_errors(true);
$dom = new DOMDocument();
$dom->loadHTML('<?xml encoding="utf-8" ?>' . $tdContent);
$contentNode = $dom->getElementsByTagName('body')->item(0);

// 组装富文本
$richText = new RichText();
foreach ($contentNode->childNodes as $node) {
    if ($node->nodeType === XML_TEXT_NODE) {
        $richText->createText($node->nodeValue);
    } elseif ($node->nodeType === XML_ELEMENT_NODE) {
        $textRun = $richText->createTextRun($node->nodeValue);
        $font = $textRun->getFont();
        // 匹配strong标签设置加粗
        if ($node->tagName === 'strong') {
            $font->setBold(true);
        }
        // 匹配em标签设置斜体
        if ($node->tagName === 'em') {
            $font->setItalic(true);
        }
    }
}

// 赋值给对应单元格
$worksheet->getCell('A1')->setValue($richText);

// 原有输出逻辑保持不变
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment;filename="export.xls"');
header('Cache-Control: max-age=0');
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xls');
$writer->save('php://output');

扩展说明

  • 如需支持更多行内格式(如字体颜色、下划线、删除线),可在解析DOM节点时读取元素的style属性,给TextRun的Font对象调用对应set方法即可实现
  • 遇到嵌套标签场景(如<strong><em>加粗斜体文本</em></strong>),需要调整DOM遍历逻辑做递归解析,将嵌套的样式属性叠加到对应文本片段上
  • 不建议直接使用原生Html读取器加载完整HTML表格来处理这类需求,因为其本身不支持富文本场景,需要逐单元格走上述组装逻辑

内容的提问来源于stack exchange,提问作者Giuseppe Lodi Rizzini

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.25 22:27:03