如何在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"和行号1;columnIndexFromString()则把列名转换为数字(比如"A"转1),方便我们转换为数组的0索引。- 索引转换:因为
toArray()返回的数组是从0开始索引的,而PhpSpreadsheet的单元格行和列是从1开始计数的,所以需要减去1来匹配数组的索引位置。
这样处理后,你就能得到所有合并单元格位置都填充了对应值的数组啦!
内容的提问来源于stack exchange,提问作者rvng




