如何在PhpSpreadsheet中通过循环插入数据并解决仅显示首条数据问题
解决PhpSpreadsheet循环合并单元格仅显示第一条数据的问题
问题根源
- 行号计算优先级错误:字符串拼接时未用括号包裹数字运算,PHP会自动转换字符串与数字的运算类型,导致行号计算出错。
- 未跟踪动态行位置:仅用数组索引
$index计算起始行,忽略了每个debitur对应的dokumen数量差异,后续数据被写入错误位置或覆盖。
修复后的代码
public function printReport() { $data = $this->allDokumenDipinjam(); if ($data) { $data = $data->values(); $spreadsheet = IOFactory::load('format/format-laporan.xlsx'); $worksheet = $spreadsheet->getActiveSheet(); // 初始化起始行,从第5行开始 $currentRow = 5; foreach ($data as $index => $debitur) { $dokumen = $debitur->dokumen->values(); $dokumenCount = count($dokumen); // 计算合并的结束行 $endRow = $currentRow + $dokumenCount - 1; // 合并A列:当前行到结束行 $worksheet->mergeCells("A{$currentRow}:A{$endRow}"); $worksheet->getCell("A{$currentRow}")->setValueExplicit($index + 1); // 合并B列 $worksheet->mergeCells("B{$currentRow}:B{$endRow}"); $worksheet->getCell("B{$currentRow}")->setValueExplicit($debitur->no_debitur); // 合并C列 $worksheet->mergeCells("C{$currentRow}:C{$endRow}"); $worksheet->getCell("C{$currentRow}")->setValueExplicit($debitur->nama_debitur); // 更新当前行,跳到下一个debitur的起始行 $currentRow += $dokumenCount; } } $writer = IOFactory::createWriter($spreadsheet, 'Xlsx'); $writer->save('tes.xlsx'); return response()->download('tes.xlsx')->deleteFileAfterSend(true); }
关键修改说明
- 新增
$currentRow变量跟踪当前写入的起始行,每次循环后根据dokumenCount更新行号,确保后续数据写入正确位置。 - 使用字符串插值
"A{$currentRow}"替代拼接,避免运算优先级问题,代码更清晰易读。 - 基于
$currentRow动态计算合并结束行,确保每个debitur的合并范围准确覆盖对应行数。
内容的提问来源于stack exchange,提问作者PinKevin
相关产品推荐
相关产品推荐

