Laravel中使用PhpSpreadsheet生成动态列Excel报表的方法
PhpSpreadsheet 动态列Excel导出实现方案
PhpSpreadsheet 原生支持任意列数的动态报表导出,调用setCellValueByColumnAndRow未达预期的核心原因是参数传值错误:该方法的列序号参数从1开始计数,1对应A列、2对应B列,传0会导致写入错位、内容不显示。
核心实现逻辑
- 从传入的动态数据集中自动提取字段作为表头,无需硬编码固定列
- 全程使用数字索引遍历列、行,不需要手动拼接A/B/C类列字母
- 适配Laravel框架响应规范,避免手动输出header导致的文件乱码、损坏问题
可直接使用的改造代码
// 注意:以下类引用需放在文件头部 use PhpOffice\PhpSpreadsheet\Spreadsheet; use PhpOffice\PhpSpreadsheet\Writer\Xlsx; use Illuminate\Support\Str; function exportExcelDownload($name, $data) { $spreadsheet = new Spreadsheet(); $sheet = $spreadsheet->getActiveSheet(); // 空数据兜底 if (empty($data)) { $sheet->setCellValue('A1', '暂无数据'); } else { // 自动提取列字段:兼容数组/对象格式的数据集 $firstRow = is_array($data[0]) ? $data[0] : get_object_vars($data[0]); $columns = array_keys($firstRow); $columnTotal = count($columns); // 写入第一行表头 foreach ($columns as $colIdx => $colName) { $sheet->setCellValueByColumnAndRow($colIdx + 1, 1, $colName); } // 逐行写入数据,行号从2开始 $rowIdx = 2; foreach ($data as $row) { $rowArr = is_array($row) ? $row : get_object_vars($row); foreach ($columns as $colIdx => $colKey) { $sheet->setCellValueByColumnAndRow( $colIdx + 1, $rowIdx, $rowArr[$colKey] ?? '' ); } $rowIdx++; } // 可选配置:自动适配列宽 foreach (range(1, $columnTotal) as $colNum) { $sheet->getColumnDimensionByColumn($colNum)->setAutoSize(true); } } $fileName = Str::finish($name, '.xlsx'); $writer = new Xlsx($spreadsheet); // 使用Laravel流式响应输出,避免乱码 return response()->streamDownload(function () use ($writer) { $writer->save('php://output'); }, $fileName, [ 'Content-Type' => 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet', ]); }
使用说明
- 代码默认取数据集第一条的键名/属性名作为表头,如果需要自定义中文表头,只需要把
$columns替换成自定义键值映射即可,例如['client' => '客户名称', 'number' => '单据编号'],表头写入映射值,数据读取对应原键即可 - 兼容数据集为对象、数组两种常见返回格式,不需要提前手动转换
- 自动列宽为可选配置,不需要可直接删除对应代码段
内容的提问来源于stack exchange,提问作者Desarrollador
相关产品推荐
相关产品推荐

