个人笔记记录
使用PhpSpreadsheet 导出excel。
多重表头生成excel 表
//读取数据库public function demo1(){// 连接spc数据库$config = Config::get('databaseedc');$db = Db::connect($config);$data =$db->name("xxxx")->alias('a')->field('main_header, sub_header,fvi_value')->join('')->where('')->select();$this->exportDataToExcel($data);}
// 将数据转换为Excel格式并保存function exportDataToExcel($data) {//从初始化表格$spreadsheet = new Spreadsheet();$sheet = $spreadsheet->getActiveSheet();// 处理数据和表头$mainHeaders = $this->getMainHeaders($data);//提取次级表头和数据$subHeadersAndData = $this->getSubHeadersAndData($data);// 设置表头$this->setHeaders($sheet, $mainHeaders, $subHeadersAndData);//设置Excel的数据$currentRow = 2;//初始行$col=1; //初始列//循环主表头foreach ($mainHeaders as $subData){//循环次级表头和数据foreach ($subHeadersAndData as $subHeaderKey => $subHeaderData) {// 获取主表头部分$mainHeaderPart = explode('_', $subHeaderKey)[0];//查找于当前表头一致的数据if($mainHeaderPart==$subData){echo("<pre>");print_r($subHeaderKey);//设置子标题:$sheet->setCellValueByColumnAndRow($col, $currentRow, $subHeaderData['sub_header']);//设置子标题相关的数据foreach ($subHeaderData['data'] as $index => $value) {$sheet->setCellValueByColumnAndRow($col, $currentRow + $index + 1, $value);}$col++;}}}// 保存文件$writer = IOFactory::createWriter($spreadsheet, 'Xlsx');$filename = './excel/' . date('YmdHis') . '.xlsx'; // 使用动态文件名避免冲突$result = $writer->save($filename);}
//从数据中提取主表头public function getMainHeaders($data) {$mainHeaders = [];foreach ($data as $item) {//检查 main_header 是否已在 $mainHeaders 中if (!in_array($item['main_header'], $mainHeaders)) {//不存在,加入数组$mainHeaders[] = $item['main_header'];}}return $mainHeaders;}
//从数据中提取次级表头和数据function getSubHeadersAndData($data) {$subHeaders = [];//存储处理后的子标题及其相关数据$rowData = [];foreach ($data as $item) {$subHeaderKey = $item['main_header'] . '_' . $item['sub_header'];//检查 $subHeaders 数组中是否已经存在该子标题键if (!isset($subHeaders[$subHeaderKey])) {$subHeaders[$subHeaderKey] = ['sub_header' => $item['sub_header'],'data' => []];}//$item 中的 'fvi_value' 添加到与该子标题关联的 'data' 数组中。$subHeaders[$subHeaderKey]['data'][] = $item['fvi_value'];}return $subHeaders;}
//设置Excel的表头function setHeaders($sheet, $mainHeaders, $subHeadersAndData) {//从第一行第一列开始$col = 1;$row = 1;//遍历主标题foreach ($mainHeaders as $mainHeader) {//设置主标题$sheet->setCellValueByColumnAndRow($col, $row, $mainHeader);//计算与当前主标题相关的子标题数量$subHeadersCount = count(array_filter(array_keys($subHeadersAndData), function($key) use ($mainHeader) {return strpos($key, $mainHeader . '_') === 0;}));//合并单元格if ($subHeadersCount > 0) {$sheet->mergeCells(Coordinate::stringFromColumnIndex($col) . $row . ':' . Coordinate::stringFromColumnIndex($col + $subHeadersCount - 1) . $row);}//更新列索引:$col += $subHeadersCount;}}