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

使用OpenTBS读取ODS文件时单元格换行内容丢失问题求助

解决ODS单元格多行文本读取截断问题(TinyButStrong+OpenTBS)

ODS格式中,单元格内的多行文本是通过多个<text:p>标签存储的,OpenTBS默认只会提取第一个<text:p>的内容,这就是你遇到内容截断的原因。以下是两种可行的解决方法:

方法1:利用OpenTBS的回调函数提前处理

通过OnXmlParsing回调在解析XML阶段直接拼接单元格内的所有<text:p>内容,确保后续获取的数据是完整的:

require_once('tinybutstrong/tbs_class.php');
require_once('opentbs/opentbs_class.php');

$TBS = new clsTinyButStrong;
$OpenTBS = new clsOpenTBS;

// 注册XML解析回调,处理多行单元格
$OpenTBS->OnXmlParsing = function($Node, $Path, $RecData) {
    // 匹配ODS单元格的text:p节点路径
    if ($Path === 'office:document-content/office:body/office:spreadsheet/table:table/table:table-row/table:table-cell/text:p') {
        $cell_node = $Node->parentNode;
        $text_p_list = $cell_node->getElementsByTagName('text:p');
        $full_content = '';
        
        foreach ($text_p_list as $p_node) {
            $text = trim($p_node->textContent);
            if (!empty($full_content)) {
                $full_content .= "\n";
            }
            $full_content .= $text;
        }
        
        // 替换当前节点内容为拼接后的完整文本
        $Node->nodeValue = $full_content;
    }
    return $RecData;
};

// 加载目标ODS文件
$OpenTBS->LoadTemplate('inferno.ods');

// 获取第一个表格的数据(可根据实际表格位置调整索引)
$sheet_data = $OpenTBS->GetSourcePart('//table:table[1]');

// 转换为PHP数组
$result_array = [];
foreach ($sheet_data->children() as $row_node) {
    $row = [];
    foreach ($row_node->children() as $cell_node) {
        // 直接取处理后的单元格文本
        $row[] = $cell_node->textContent;
    }
    $result_array[] = $row;
}

print_r($result_array);

方法2:手动遍历XML节点处理

如果回调方式不适用,也可以直接解析XML内容,手动遍历单元格内的所有<text:p>标签拼接内容:

require_once('tinybutstrong/tbs_class.php');
require_once('opentbs/opentbs_class.php');

$TBS = new clsTinyButStrong;
$OpenTBS = new clsOpenTBS;
$OpenTBS->LoadTemplate('inferno.ods');

// 获取原始XML内容
$xml_content = $TBS->Source;
$xml = simplexml_load_string($xml_content);

// 注册ODS所需的XML命名空间
$xml->registerXPathNamespace('office', 'urn:oasis:names:tc:opendocument:xmlns:office:1.0');
$xml->registerXPathNamespace('table', 'urn:oasis:names:tc:opendocument:xmlns:table:1.0');
$xml->registerXPathNamespace('text', 'urn:oasis:names:tc:opendocument:xmlns:text:1.0');

// 遍历所有行和单元格
$result_array = [];
$rows = $xml->xpath('//table:table-row');
foreach ($rows as $row) {
    $cells = $row->xpath('./table:table-cell');
    $row_data = [];
    
    foreach ($cells as $cell) {
        $p_tags = $cell->xpath('./text:p');
        $cell_text = '';
        
        foreach ($p_tags as $p) {
            $text = trim((string)$p);
            if (!empty($cell_text)) {
                $cell_text .= "\n";
            }
            $cell_text .= $text;
        }
        
        $row_data[] = $cell_text;
    }
    $result_array[] = $row_data;
}

print_r($result_array);

关键注意点

  • ODS的XML使用了命名空间,必须通过registerXPathNamespace注册对应命名空间才能正确定位节点,这是很多人用SimpleXML解析失败的核心原因。
  • 拼接时可以根据需求选择换行符(\n或\r\n),或者用其他分隔符。

内容的提问来源于stack exchange,提问作者sariDon

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.08 10:15:14