php使用PhpOffice\PhpSpreadsheet 实现Excel导出

作者: 分类: php 发布时间: 2021-03-29 11:23 浏览人数:5
 

最近要做一个这样的导出,把数据库所查询出来的数据,一键导出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表格就是如下图:


如果觉得我的文章对您有用,请随意打赏。您的支持将鼓励我继续创作!