最近公司需要用到一个省市区三级联动的excel表格,但是数据都在数据库,又太多,人工不好制作,就让我这个phper来帮忙啦。
主要用到的是excel的定义名称,数据验证。其中数据验证的列表只能是一列或者一行,网上查了下说可以先用一行做数据验证,然后修改名称的定义范围,经过我尝试,效果不好。
然后我把顶级名称的东西放到了表格的“无人地带”,解决了问题,也算是耍了个小聪明吧。
效果图:
代码片段(php):
public function actionTest2()
{
$subject = \'demo\';
$title = [\'省\',\'市\',\'区\'];
$data = [
[
\'name\' => \'湖北省\',
\'children\' => [
[
\'name\' => \'武汉市\',
\'children\' => [\'江夏区\',\'洪山区\',\'青山区\',\'武昌区\',\'汉口\']
],
[
\'name\' => \'宜昌市\',
\'children\' => [\'当阳市\',\'夷陵区\',\'庙前\']
],
[
\'name\' => \'荆州市\',
\'children\' => [\'荆州区\',\'荆州城区\']
]
]
],
[
\'name\' => \'湖南省\',
\'children\' => [
[
\'name\' => \'长沙市\',
\'children\' => [\'长沙1\',\'长沙2\',\'长沙3\',\'长沙4\',\'长沙5\',\'长沙6\',\'长沙7\']
],
[
\'name\' => \'岳阳市\',
\'children\' => [\'岳阳市1\',\'益阳市\']
],
[
\'name\' => \'常德市\',
\'children\' => [\'常德山庄1\',\'常德山庄2\',\'常德山庄3\']
]
]
],
[
\'name\' => \'广东省\',
\'children\' => [
[
\'name\' => \'广东市\',
\'children\' => [\'广东市1\',\'广东市2\',\'广东市3\']
],
[
\'name\' => \'深圳\',
\'children\' => [\'深圳1\',\'深圳2\',\'深圳3\']
],
[
\'name\' => \'佛山市\',
\'children\' => [\'佛山1\',\'佛山2\',\'佛山3\',\'佛山4\',\'佛山5\']
]
]
],
];
$high = 0;
$objPHPExcel = new \PHPExcel();
$titleRow = array(\'A1\',\'B1\',\'C1\',\'D1\',\'E1\',\'F1\',\'G1\',\'H1\',\'I1\',\'J1\',\'K1\',\'L1\',\'M1\',\'N1\',\'O1\',\'P1\',\'Q1\',\'R1\',\'S1\',\'T1\',\'U1\',\'V1\',\'W1\',\'X1\',\'Y1\',\'Z1\',\'AA1\',\'AB1\',\'AC1\',\'AD1\');
for($a = 0; $a < count($title); $a++){
$objPHPExcel->setActiveSheetIndex(0)->setCellValue($titleRow[$a], $title[$a]);
}
$supportSheet = new \PHPExcel_Worksheet($objPHPExcel, \'support\'); //创建一个工作表
$objPHPExcel->addSheet($supportSheet); //插入工作表
$col = [\'A\',\'B\',\'C\',\'D\',\'E\',\'F\',\'G\',\'H\',\'I\',\'J\',\'K\',\'L\',\'M\',\'N\',\'O\',\'P\',\'Q\',\'R\',\'S\',\'T\',\'U\',\'V\',\'W\',\'X\',\'Y\',\'Z\'];
foreach ($data as $key=>$first){
$objPHPExcel->getSheetByName(\'support\')->setCellValue($col[0].($key+1+$high),$first[\'name\']);
$max = 0; //重置max
$secondNum = count($first[\'children\']);
foreach ($first[\'children\'] as $index=>$second){
$objPHPExcel->getSheetByName(\'support\')->setCellValue($col[$index+1].($key+1+$high),$second[\'name\']);
$thirdNum = count($second[\'children\']);
if ($thirdNum > $max){
$max = $thirdNum;
}
foreach ($second[\'children\'] as $id=>$third){
$objPHPExcel->getSheetByName(\'support\')->setCellValue($col[$index+1].($key+1+$high+$id+1),$third);
}
//定义三级名称
$objPHPExcel->addNamedRange(
new \PHPExcel_NamedRange(
$second[\'name\'],
$objPHPExcel->getSheetByName(\'support\'),
$col[$index+1].($key+1+$high+1).\':\'.$col[$index+1].($key+1+$high+1+$thirdNum-1)
)
);
}
//定义二级名称
$objPHPExcel->addNamedRange(
new \PHPExcel_NamedRange(
$first[\'name\'],
$objPHPExcel->getSheetByName(\'support\'),
$col[1].($key+1+$high).\':\'.$col[1+$secondNum-1].($key+1+$high)
)
);
$high += $max;
}
//移花接木
foreach ($data as $var=>$content){
$objPHPExcel->getSheetByName(\'support\')->setCellValue(\'UI\'.($var+1),$content[\'name\']);
}
//定义顶级名称
/*$total = count($data);
$str = \'\';
$count = 0;
$max = 0;
for ($i = 0;$i < $total;$i++){
$str .= $col[0].(1+$count+$i).\',\';
$secondCount = count($data[$i][\'children\']);
for ($j = 0;$j < $secondCount;$j++){
if (count($data[$i][\'children\'][$j][\'children\']) > $max){
$max = count($data[$i][\'children\'][$j][\'children\']);
}
}
$count += $max;
}
$str = rtrim($str,\',\');
$objPHPExcel->addNamedRange(
new \PHPExcel_NamedRange(
\'region\',
$objPHPExcel->getSheetByName(\'support\'),
$str
)
);*/
$total = count($data);
$objPHPExcel->addNamedRange(
new \PHPExcel_NamedRange(
\'region\',
$objPHPExcel->getSheetByName(\'support\'),
\'UI1\'.\':\'.\'UI\'.$total
)
);
//数据验证
for ($i = 2;$i < 10;$i++){
$objValidation = $objPHPExcel->getActiveSheet()->getCell(\'A\'.$i)->getDataValidation();
$objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );
$objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
$objValidation->setAllowBlank(false);
$objValidation->setShowInputMessage(true);
$objValidation->setShowErrorMessage(true);
$objValidation->setShowDropDown(true);
$objValidation->setErrorTitle(\'输入错误\');
$objValidation->setError(\'不在列表中的值\');
$objValidation->setPromptTitle(\'请选择\');
$objValidation->setPrompt(\'请从列表中选择一个值.\');
$objValidation->setFormula1("=region");
$objValidation = $objPHPExcel->getActiveSheet()->getCell(\'B\'.$i)->getDataValidation();
$objValidation->setType(\PHPExcel_Cell_DataValidation::TYPE_LIST );
$objValidation->setErrorStyle(\PHPExcel_Cell_DataValidation::STYLE_INFORMATION );
$objValidation->setAllowBlank(false);
$objValidation->setShowInputMessage(true);
$objValidation->setShowErrorMessage(true);
$objValidation->setShowDropDown(true);
$objValidation->setErrorTitle(\'输入错误\');
$objValidation->setError(\'不在列表中的值\');
$objValidation->setPromptTitle(\'请选择\');
$objValidation->setPrompt(\'请从列表中选择一个值.\');
$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->setAllowBlank(false);
$objValidation->setShowInputMessage(true);
$objValidation->setShowErrorMessage(true);
$objValidation->setShowDropDown(true);
$objValidation->setErrorTitle(\'输入错误\');
$objValidation->setError(\'不在列表中的值\');
$objValidation->setPromptTitle(\'请选择\');
$objValidation->setPrompt(\'请从列表中选择一个值.\');
$objValidation->setFormula1(\'=INDIRECT($\'.\'B\'.\'$\'.$i.\')\');
}
$objPHPExcel->setActiveSheetIndex(0);
//输出表格
header(\'Content-Type: application/vnd.ms-excel\');
header(\'Content-Disposition: attachment;filename=\'.$subject.\'\'.date(\'Ymd\').\'.xlsx\');
header(\'Cache-Control: max-age=0\');
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, \'Excel2007\');
$objWriter->save(\'php://output\');
}