PHP使用PhpOffice\PhpSpreadsheet 实现Excel导出
最近要做一个这样的导出,把数据库所查询出来的数据,一键导出Excel。
使用PhpOffice\PhpSpreadsheet实现。
使用composer安装PhpSpreadsheet到你的项目:
composer require phpoffice/phpspreadsheet
直接上代码:
// 这里为tp框架model层查询出来的数据,并转换为数组形式
$signupRecord = $signupRecord->select()->toArray();
// 这里为excel表标题,是否需要看个人需求
$title = '报名表';
/* 这里为重点,将所有要导出的数据字段,按照
* ```
* '列名(例如:“A”)' => [
* 'title' => '列标题(或者是数据表字段注释,例如:“ID”)',
* 'field' => '数据表字段名(例如:“id”)'
* ]
* ```
* 的格式,写进$title_row
*
*/
$title_row = array(
'A' => ['title' => 'ID', 'field' => 'id'],
'B' => ['title' => '报名表标题', 'field' => 'signup_info_name'],
'C' => ['title' => '课程标题', 'field' => 'class_info_name'],
'D' => ['title' => '学员姓名', 'field' => 'student_info_stu_name'],
'E' => ['title' => '报名时间', 'field' => 'c_time'],
'F' => ['title' => '开课时间', 'field' => 'class_info_start_time'],
);
// 设置excel表默认样式
$styleArray = [
'alignment' => [
'horizontal' => Alignment::HORIZONTAL_CENTER,
'vertical' => Alignment::VERTICAL_CENTER,
],
'font' => [
'name' => '宋体',
'size' => 11,
],
];
// 创建sheet
$spreadsheet = new Spreadsheet();
// 应用上面所写的样式
$spreadsheet->getDefaultStyle()->applyFromArray($styleArray);
// 设置当前的活动sheet
$sheet = $spreadsheet->setActiveSheetIndex(0);
// 合并标题栏,这里会自动根据要导出的数据字段的数量,自动合并项对应列数量的列
// 前提是每一个字段只占一列
$sheet->mergeCells(
array_keys($title_row)[0].'1'.
':'.
array_keys($title_row)[count($title_row)-1].'1'
);
$sheet->getStyle('A1')->getFont()->setSize(28);
$sheet->getStyle('A1')->getAlignment()->setHorizontal(Alignment::HORIZONTAL_CENTER);
$sheet->setCellValueExplicit(
'A1',
$title,
DataType::TYPE_STRING2
);
// 根据上面$title_row所设置的要导出的列,一一对应填写在每一列中
foreach ($title_row as $key => $value) {
$sheet->getStyle($key.'2')->getFont()->setBold(true);
$sheet->getColumnDimension($key)->setWidth(22.25);
$sheet->setCellValueExplicit(
$key.'2',
$value['title'],
DataType::TYPE_STRING2
);
}
// 设置当前遍历的行数,这里从第2行开始。
// 遍历的时候先自增,然后再使用。
// 如果先使用后自增,到最后面加边框的时候会多出一行空白行。
$current_row = 2;
// 遍历每一条查询出来的数据
foreach ($signupRecord as $key => $value) {
$current_row++;
// 遍历每一个所设置要导出的字段
foreach ($title_row as $title_row_key => $title_row_value) {
$sheet->setCellValueExplicit(
// 当前列号 . 当前行号
$title_row_key.$current_row,
// $title_row_value['field']为当前列的数据字段名
// 所以$value[$title_row_value['field']]就可以拿到当前数据对应值字段名的数据了
$value[$title_row_value['field']],
DataType::TYPE_STRING2
);
}
}
// 边框样式
$borderStyle = [
'borders' => [
'allBorders' => [
'borderStyle' => Border::BORDER_THIN //细边框
]
]
];
// 给当前excel表除了大标题行以外(即第1行除外),添加边框
$sheet->getStyle(
array_keys($title_row)[0].'2'.
':'.
array_keys($title_row)[count($title_row)-1].$current_row
)->applyFromArray($borderStyle);
// 这里为冻结窗格,看需求咯
// $sheet->freezePane(array_keys($title_row)[count($title_row)-1].'2', array_keys($title_row)[0].'1');
// 设置header,导出excel表
// Redirect output to a client’s web browser (Xlsx)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="'.$title.'_'.date('Y-m-d').'.xlsx"');
header('Cache-Control: max-age=0');
// If you're serving to IE 9, then the following may be needed
header('Cache-Control: max-age=1');
// If you're serving to IE over SSL, then the following may be needed
header('Expires: Mon, 26 Jul 1997 05:00:00 GMT'); // Date in the past
header('Last-Modified: ' . gmdate('D, d M Y H:i:s') . ' GMT'); // always modified
header('Cache-Control: cache, must-revalidate'); // HTTP/1.1
header('Pragma: public'); // HTTP/1.0
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$writer->save('php://output');
exit;
最终导出来的excel表格就是如下图: