You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多
文档控制台
免费开始使用

如何在PhpSpreadsheet中读取合并单元格的值

解决PhpSpreadsheet读取合并单元格时仅起始单元格有值的问题

嘿,我之前也碰到过这个坑!PhpSpreadsheet的toArray()方法默认确实只在合并区域的第一个单元格保留值,其余位置都是null。不过咱们可以通过手动处理合并单元格的信息,把值填充到所有对应的数组位置里,具体做法如下:

核心思路

先获取工作表中所有的合并单元格区域,然后针对每个区域,取出起始单元格的值,再遍历该区域内的所有单元格位置,把值同步填充到$sheetData数组对应的索引里。

完整代码示例

$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx(); 
$spreadsheet = $reader->load($_FILES['mapping_file']['tmp_name']); 
$worksheet = $spreadsheet->getActiveSheet();
$sheetData = $worksheet->toArray();

// 获取当前工作表中所有的合并单元格区域
$mergedCells = $worksheet->getMergeCells();

// 遍历每个合并区域进行值填充
foreach ($mergedCells as $mergedRange) {
    // 将合并区域字符串(如"A1:C3")拆分为起始和结束单元格
    list($startCell, $endCell) = explode(':', $mergedRange);
    
    // 解析起始单元格的坐标,转换为数组的0索引(PhpSpreadsheet行/列从1开始,数组从0开始)
    $startCoords = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::coordinateFromString($startCell);
    $startRowIdx = $startCoords[1] - 1;
    $startColIdx = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($startCoords[0]) - 1;
    
    // 解析结束单元格的坐标,同样转换为0索引
    $endCoords = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::coordinateFromString($endCell);
    $endRowIdx = $endCoords[1] - 1;
    $endColIdx = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($endCoords[0]) - 1;
    
    // 获取合并单元格的实际值(起始单元格的值)
    $mergedValue = $sheetData[$startRowIdx][$startColIdx];
    
    // 遍历合并区域内的所有行和列,填充值
    for ($row = $startRowIdx; $row <= $endRowIdx; $row++) {
        for ($col = $startColIdx; $col <= $endColIdx; $col++) {
            $sheetData[$row][$col] = $mergedValue;
        }
    }
}

// 现在$sheetData中的所有合并单元格位置都已填充对应值

关键细节说明

  • getMergeCells():这个方法会返回当前工作表中所有合并单元格的区域字符串,格式类似"A1:C3"
  • coordinateFromString():用于解析单元格坐标,把"A1"拆分为列名"A"和行号1columnIndexFromString()则把列名转换为数字(比如"A"转1),方便我们转换为数组的0索引。
  • 索引转换:因为toArray()返回的数组是从0开始索引的,而PhpSpreadsheet的单元格行和列是从1开始计数的,所以需要减去1来匹配数组的索引位置。

这样处理后,你就能得到所有合并单元格位置都填充了对应值的数组啦!

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

火山引擎 最新活动