赞
踩
多重表头生成excel 表
//读取数据库 public function demo1() { // 连接数据库 $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; }
getSubHeadersAndData 中的数组如下。 “主表头_次级表头” 为了方便记录次级表头所属的表头是哪个。
sub_header:次级表头
data:当前列的内容。
//设置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; } }
第一行是主表头。第二行是次级表头。
对其方式
靠右:HORIZONTAL_RIGHT
靠左:HORIZONTAL_LEFT
居中:HORIZONTAL_CENTER
// 设置该单元格左对齐 $style = $sheet->getStyleByColumnAndRow($col, $currentRow); $style->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); //合并单元格 // 合并单元格,例如合并A1到B2的区域 //方法1 $sheet->mergeCells('A1:B2'); //方法2 $col = 1;//列 $row = 1;//行 //Coordinate::stringFromColumnIndex($col) //将起始列的数值索引转换为列名。 //. $row //将行号附加到列名的后面,形成起始单元格的完整坐标(如 'A1')。 //Coordinate::stringFromColumnIndex($col + $subHeadersCount - 1) //将结束列的数值索引(起始列加上需要合并的列数减 1)转换为列名。 //. $row //同样将行号附加到结束列的列名后面,形成结束单元格的完整坐标。 $sheet->mergeCells(Coordinate::stringFromColumnIndex($col) . $row . ':' . Coordinate::stringFromColumnIndex($col + $subHeadersCount - 1) . $row);
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。