当前位置:   article > 正文

PhpSpreadsheet表格导出

PhpSpreadsheet表格导出
个人笔记记录

使用PhpSpreadsheet 导出excel

多重表头生成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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
    // 将数据转换为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);
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22
  • 23
  • 24
  • 25
  • 26
  • 27
  • 28
  • 29
  • 30
  • 31
  • 32
  • 33
  • 34
  • 35
  • 36
  • 37
  • 38
  • 39
  • 40
  • 41
  • 42
  • 43
  • 44
  • 45
  • 46
  • 47
  • 48
    //从数据中提取主表头
    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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
    //从数据中提取次级表头和数据
    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;
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18

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;
        }
    }
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
  • 22

第一行是主表头。第二行是次级表头。
在这里插入图片描述

补充

对其方式
靠右: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);
  • 1
  • 2
  • 3
  • 4
  • 5
  • 6
  • 7
  • 8
  • 9
  • 10
  • 11
  • 12
  • 13
  • 14
  • 15
  • 16
  • 17
  • 18
  • 19
  • 20
  • 21
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/2023面试高手/article/detail/684480
推荐阅读
相关标签
  

闽ICP备14008679号