使用PHP导出Excel时,如果是一级表头处理起来很简单,但如果碰到复杂一点的表头,比如二级、三级,甚至更多级别的表头要怎么办呢?
就像下面这个表头,有三层,并且每层都不太规则——
难道我们每次处理表头都要一列一列地拆分或者合并单元格吗?
当然不用,我们换个思路:
直接不处理表头,将一个含复杂表头的现成模板放到服务器,调用方法时下载模板文件,再把数据装进去,保存下来。
那就完全不用担心表头有多复杂的问题。
废话不多说,直接上现成代码!!!
/**
* 导出固定模板的excel文件(支持.xls、.xlsx格式)
* (
* 该方法主要用于导出复杂表头【如:2、3级表头等】的excel文件:
* 1. 先将模板文件放到系统目录下;
* 2. 调用方法时,将从系统目录下载模板文件,并将数据插入到excel模板对应的列数【不识别表头】当中
* 3. 保存文件并返回文件名
* )
* @param $modelExcelPath 模板excel的文件路径(推荐使用系统相对路径,如:../runtime/obs/Excel模板.xls)
* @param $fileName 文件名
* @param $data 导出数据
* @return string $fileName 文件名
*/
public static function exportExcel($modelExcelPath, $fileName = '', $data = '')
{
try{
// 加载excel
try {
$inputFileType = \PHPExcel_IOFactory::identify($modelExcelPath);
$objReader = \PHPExcel_IOFactory::createReader($inputFileType);
$objPHPExcel = $objReader->load($modelExcelPath);
} catch(\Exception $e) {
die('加载Excel发生错误:"'.pathinfo($modelExcelPath,PATHINFO_BASENAME).'": '.$e->getMessage());
}
// excel列数
$cellName = ['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',
'AA', 'AB', 'AC', 'AD', 'AE', 'AF', 'AG', 'AH', 'AI', 'AJ', 'AK', 'AL', 'AM', 'AN', 'AO', 'AP', 'AQ', 'AR', 'AS', 'AT', 'AU', 'AV', 'AW', 'AX', 'AY', 'AZ'];
// 处理数据
$sheet = $objPHPExcel->getSheet(0); // 读取第一個工作表
$maxRow = $sheet->getHighestRow(); // 取得总行数
foreach($data as $val){
$i = 0; //列数
$maxRow++; // 循环操作行的行号
foreach ($val as $key => $item){
$objPHPExcel->getActiveSheet()->setCellValue($cellName[$i] . $maxRow, $item);
$i++;
}
}
// 文件类型
$fileType = pathinfo($modelExcelPath, PATHINFO_EXTENSION);
$objWriter = \PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel5');
// 文件名
if (empty($fileName)) {
$fileName = "excel-" . date("YmdHis", time()) . rand(1000, 9999) . "." . $fileType;
}else{
$fileName = $fileName . date("YmdHis", time()) . rand(1000, 9999) . '.' . $fileType;
}
$file = \Env::get('runtime_path') . '/export/' . $fileName;
// 保存文件并返回
$objWriter->save($file);
return $fileName;
}catch(\Exception $exception) {
throw new \Exception('出错了!');
}
}