在一个项目中集成了PhpSpreadsheet,试图将平台的部分数据导出为Excel,为此专门封装了一个Office服务组件。但是好巧不巧导出的Excel文件竟然是空白的。如下图所示:
Tp-admin框架中Office组件源码参考:https://gitee.com/zkii_admin/Tp-admin/blob/master/extend/service/OfficeService.php
其中有个导出Excel文件的方法是这样写的。
- /**
- * 导出Excel2
- * @param $list Array 数据列
- * @param $filename String 文件名
- * @param $title String 标题
- * @param $keys Array 字段与说明
- */
- public function toExcelWithHead($list,$filename,$title,$keys){
- $sheet = new Spreadsheet();
- $begin = 1;
- $filename = empty($filename) ? time().".xlsx" : $filename.".xlsx";
- $keymap = array_column($keys,'notes');
- $filedmap = array_column($keys,'fields');
- $col_num = sizeof($keymap);
- if(!empty($title)){
- $sheet->getProperties()->setTitle($title);
- $sheet->getActiveSheet()->setCellValue('A1',$title);
- $sheet->getActiveSheet()->getStyle('A1')->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
- $sheet->getActiveSheet()->mergeCells('A1:'.self::$cellKey[$col_num-1].'1');
- $begin +=1;
- }
- if(!empty($keymap)){
- for($i=0;$i<$col_num;$i++){
- $sheet->getActiveSheet()->getStyle(self::$cellKey[$i].$begin)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
- $sheet->setActiveSheetIndex(0)->setCellValue(self::$cellKey[$i].$begin,mb_convert_encoding($keymap[$i],'utf-8'));
- }
- $begin +=1;
- }
- $leng = sizeof($list);
- for($row = 0;$row < $leng;$row++){
- $j = $row+$begin;
- for($t=0;$t<$col_num;$t++){
- $sheet->getActiveSheet()->setCellValueByColumnAndRow($t+1,$j,mb_convert_encoding($list[$row][$filedmap[$t]],'utf-8'));
- }
- }
- ob_end_clean();
- header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
- header('Content-Disposition: attachment; filename="' . $filename . '"');
- header('Cache-Control: max-age=0');
- $writer = IOFactory::createWriter($sheet, 'Xlsx');
- $writer->save('php://output');
- }
经过排查后发现是传入$keys数据格式不正确导致的,$keymap的元素个数为0,导致第一行没有元素,输出Excel成空白文件。
后来传入$keys格式变成如下格式的数组,输出Excel正常。
- array(
- array("fields"=>"id","notes"=>"序号");
- array("fields"=>"name","notes"=>"名称");
- ...
- );