主要用到PHPexcel下的几个方法:

  1.创建工作表:

$objPHPExcel = new \PHPExcel();
$objPHPExcel->createSheet();//创建工作表
$dataSheet = $objPHPExcel->getSheet(1);	//获取工作表
$dataSheet->setTitle('drop_list_data');//设置工作表名称

  

  2.创建筛选项

$objPHPExcel->addNamedRange(
    new \PHPExcel_NamedRange(
        $province['name'], //筛选项名称
        $dataSheet, //所在工作表
        'B1:B6' //工作表位置坐标
    )
);

  3.数据验证

$objValidation = $objPHPExcel->getActiveSheet()->getCell("B".$i)->getDataValidation();//获取需要验证的单元格
$objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );//验证类型 有TYPE_LIST,TYPE_TIME,TYPE_DATE,TYPE_DECIMAL等
$objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );//设置报错样式  有 STYLE_STOP,STYLE_WARNING,STYLE_INFORMATION
$objValidation->setShowDropDown(true);//单元格是否显示下拉按钮
$objValidation->setAllowBlank(false);//单元格是否允许为空
$objValidation->setShowInputMessage(true);//选择时是否显示提示信息
$objValidation->setPromptTitle('请选择城市');//提示信息标题
$objValidation->setPrompt('请从列表中选择一个值.');//提示信息描述
$objValidation->setShowErrorMessage(true);//是否显示错误信息
$objValidation->setErrorTitle('输入错误');//错误时显示的错误标题
$objValidation->setError('不在列表中的值');//错误时显示的错误描述
$objValidation->setFormula1('INDIRECT($A$'.$i.')');//下拉框数据

  4.下拉框数据来源

$objValidation = $objPHPExcel->getActiveSheet()->getCell("B1")->getDataValidation();
//方式1 字符串给定 必须单引号内放入双引号
$objValidation->setFormula1('"select1,select2,select3"');
//方式2 当前工作表内数据
$objValidation->setFormula1('A1:C1');
//方式3 其他工作表内数据
$objValidation->setFormula1('drop_list_data!A1:A3');
//方式4 PHPExcel_NamedRange的名字
$objValidation->setFormula1('=range_name');

源码:

   源码中的三级循环主要为了生成如下数据:

element 省市区数据 excel省市区_ci

<?php
    require_once "./Classes/PHPExcel.php";
    
    $objPHPExcel = new \PHPExcel();
    $objPHPExcel->getProperties()->setCreator("test");
    $workSheet = $objPHPExcel->getActiveSheet();
    
    //创建用于存储筛选数据的工作表
    $objPHPExcel->createSheet();
    $dataSheet = $objPHPExcel->getSheet(1);    
    //创建完成之后 可以对齐隐藏
    $dataSheet->setTitle('drop_list_data');//->setSheetState(\PHPExcel_Worksheet::SHEETSTATE_HIDDEN);
    //省市区数据
    $sources = [
        [
            'name' => '江苏',
            'children' => [
                [
                    'name' => '南京',
                    'children' => ['玄武区', '鼓楼区', '建邺区']
                ],
                [
                    'name' => '无锡',
                    'children' => ['滨湖区', '梁溪区', '新吴区']
                ],
                [
                    'name' => '徐州',
                    'children' => ['云龙区', '鼓楼区', '贾汪区']
                ]
            ]
        ],
        [
            'name' => '山东',
            'children' => [
                [
                    'name' => '济南',
                    'children' => ['历下区', '市中区', '槐荫区']
                ],
                [
                    'name' => '青岛',
                    'children' => ['市南区', '市北区', '李沧区']
                ],
                [
                    'name' => '淄博',
                    'children' => ['张店区', '淄川区', '周村区']
                ]
            ]
        ],
        [
            'name' => '安徽',
            'children' => [
                [
                    'name' => '合肥',
                    'children' => ['瑶海区', '庐阳区', '蜀山区']
                ],
                [
                    'name' => '芜湖',
                    'children' => ['镜湖区', '弋江区', '鸠江区']
                ],
                [
                    'name' => '南京',//蚌埠
                    'children' => ['龙子湖区', '蚌山区', '禹会区']
                ]
            ]
        ]
    ];
    //所有省份的起止行
    $provinceStart = $provinceEnd = 0;
    //各省份下城市的起止行
    $cityStart = $cityEnd = 0;
    //各城市下区县的起止行
    $areaStart = $areaEnd = 0;
    //循环1.循环省份
    foreach ($sources as $sk => $province) {
        if ($sk == 0) {
            $provinceStart = $provinceEnd + 1;
        }
        $provinceEnd++;//结束行递增
        $dataSheet->setCellValue('A'.$provinceEnd, $province['name']);//设置单元格省份名称
        //循环2.循环省份下城市
        foreach ($province['children'] as $pk => $city) {//A是0
            if ($pk == 0) {
                $cityStart = $cityEnd + 1;//省份城市的开始行 等于 上个省份城市结束行+1
            }
            $cityEnd ++;//结束行递增
            $dataSheet->setCellValue('B'.$cityEnd, $city['name']);
            //循环3.循环城市下区县
            foreach ($city['children'] as $ck => $area) {
                if ($ck == 0) {
                    $areaStart = $areaEnd + 1;//城市下区县的开始行 等于 上个城市下区县的结束行+1
                }
                $areaEnd ++;//结束行递增
                $dataSheet->setCellValue('C'.$areaEnd, $area);
            }
            //城市下的区县循环结束后 合并为列表;列表的name值为 省份-城市,防止名称重复
            $objPHPExcel->addNamedRange(
                new \PHPExcel_NamedRange(
                    $province['name'].$city['name'],//列表的名
                    $dataSheet,//所在工作表
                    'C'.$areaStart.':C'.$areaEnd//单元格范围
                )
            );
        }
        //省份下的城市循环结束后,合并为列表
        $objPHPExcel->addNamedRange(
            new \PHPExcel_NamedRange(
                $province['name'],
                $dataSheet,
                'B'.$cityStart.':B'.$cityEnd
            )
        );
    }
    //省份循环结束,合并为列表
    $objPHPExcel->addNamedRange(
        new \PHPExcel_NamedRange(
            'province',
            $dataSheet,
            'A'.$provinceStart.':A'.$provinceEnd
        )
    );
    
    $workSheet->setCellValue('A1', '省份');
    $workSheet->setCellValue('B1', '城市');
    $workSheet->setCellValue('C1', '区县');    
    
    for ($i=2; $i<=500; $i++) {
        $objValidation = $workSheet->getCell("A".$i)->getDataValidation();
        $objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );
        $objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
        $objValidation->setShowDropDown(true);
        $objValidation->setAllowBlank(false);
        $objValidation->setShowInputMessage(true);
        $objValidation->setPromptTitle('请选择省份');
        $objValidation->setPrompt('请从列表中选择一个值.');
        $objValidation->setShowErrorMessage(true);
        $objValidation->setErrorTitle('输入错误');
        $objValidation->setError('不在列表中的值');
        $objValidation->setFormula1("province");
        
        
        $objValidation = $objPHPExcel->getActiveSheet()->getCell("B".$i)->getDataValidation();
        $objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );
        $objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
        $objValidation->setShowDropDown(true);
        $objValidation->setAllowBlank(false);
        $objValidation->setShowInputMessage(true);
        $objValidation->setPromptTitle('请选择城市');
        $objValidation->setPrompt('请从列表中选择一个值.');
        $objValidation->setShowErrorMessage(true);
        $objValidation->setErrorTitle('输入错误');
        $objValidation->setError('不在列表中的值');
        $objValidation->setFormula1('INDIRECT($A$'.$i.')');
        
        $objValidation = $objPHPExcel->getActiveSheet()->getCell("C".$i)->getDataValidation();
        $objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );
        $objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
        $objValidation->setShowDropDown(true);
        $objValidation->setAllowBlank(false);
        $objValidation->setShowInputMessage(true);
        $objValidation->setPromptTitle('请选择区县');
        $objValidation->setPrompt('请从列表中选择一个值.');
        $objValidation->setShowErrorMessage(true);
        $objValidation->setErrorTitle('输入错误');
        $objValidation->setError('不在列表中的值');
        $objValidation->setFormula1('=INDIRECT(CONCATENATE($A$'.$i.',$B$'.$i.'))');
    }
        
    $objPHPExcel->setActiveSheetIndex(0);
    $objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');
    $objWriter->save('./aaa.xls');