最近刚好再看 datatables 的客户端导出 api 。不是很方便,封了一个服务端导出的方法。 后面又新增了一个,差别不大,自己选择吧。
导出效果
嗯 PHP 是世界上最好的语言.jpg
/**
* @author Hiking,Lin
* @attention 需要自己引入PHPExcel类 和 IOFactory.php文件。
* @attention 数据处理机制基于WordPress 请替换为自己框架处理方式。
* @attention 标题默认拿的字段备注信息! 没有则为null
* @attention 标题默认字号为size:10 字体为微软雅黑
* @param $table_name 需要导出的数据表名。
* @param $field 需要导出的字段名 默认为所有字段信息。
* @param $file_name 导出excel文件名,没有设置则随机生成
* @param $sheet $sheet的名字 没有设置则为 sheet1
* @param $start_field_name导出数据的时间过滤依据字段 e.g. create_date
* @param $start_date 导出数据的时间过滤.开始时间 e.g. 2017-09-04 10:00:00
* @param $end_date 导出数据的时间过滤.结束时间 e.g. 2018-09-04 10:00:00
*/
public function class_get_excel( $table_name,$field = [],$file_name = '', $sheet='',$start_field_name = '',$start_date = '', $end_date = ''){
// 是否接收到数据表名
if ( empty( $table_name ) ) {
return ['code'=>'999','message'=>'需要导出的数据表名未接收到',data=>''];
}
// field 需要导出的字段名
$sql = "show full columns from $table_name";
$res = $this->wpdb->get_results( $sql,ARRAY_A );
if ( count( $field ) < 1 ) {
$field = '*';
// $title单元格标题头 默认拿的字段的注释
$excel_title = array_column( $res,'Comment' );
}else{
$excel_arr = array_column( $res,'Comment','Field' );
foreach ($field as $key => $value) {
$excel_title[] = $excel_arr[$value];
}
$field = join( ',',$field );
}
if ( empty( $start_field_name ) || empty( $start_date ) || empty( $end_date ) ) {
$data_sql = "SELECT $field FROM $table_name";
}else{
$data_sql = "SELECT $field FROM $table_name WHERE 1 AND $start_field_name BETWEEN '{$start_date}' AND '{$end_date}' ";
}
$data_res = $this->wpdb->get_results( $data_sql,ARRAY_A );
// 实例化 PHPExcel 类
$obj = new PHPExcel();
$objSheet = $obj->getActiveSheet();
$objSheet->getDefaultStyle()->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER)->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);//设置excel文件默认水平垂直方向居中
$objSheet->getStyle("A1:Z1")->getFont()->setSize(16)->setBold(true); //设置第二行字体大小和加粗
$objSheet->getDefaultStyle()->getFont()->setSize(10)->setName("微软雅黑"); //设置默认字体大小和格式
// 第一行的默认高度
$obj->getActiveSheet()->getRowDimension('1')->setRowHeight(30);
//横向单元格标识
$cellName = array('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 = empty( $sheet ) ? 'sheet1' : $sheet;
$obj->getActiveSheet(0)->setTitle( $sheet ); //设置sheet名称
$_row = 1; //设置纵向单元格标识
if( $excel_title ) {
$_cnt = count( $excel_title );
$obj->getActiveSheet(0)->mergeCells('A'.$_row.':'.$cellName[$_cnt-1].$_row); //合并单元格
$obj->setActiveSheetIndex(0)->setCellValue('A'.$_row, '数据导出:'.date('Y-m-d H:i:s')); //设置合并后的单元格内容
//垂直居中
// $obj->getActiveSheet()->getStyle('A')->getAlignment()->setVertical( PHPExcel_Style_Alignment::VERTICAL_CENTER );
$_row++;
$i = 0;
foreach( $excel_title AS $v ){ //设置列标题
$obj->setActiveSheetIndex(0)->setCellValue($cellName[$i].$_row, $v);
$i++;
}
$_row++;
}
//填写数据
if( $data_res ){
$i = 0;
foreach($data_res AS $_v){
$j = 0;
foreach($_v AS $_cell){
$obj->getActiveSheet(0)->setCellValue( $cellName[ $j ] . ( $i + $_row ), $_cell);
$j++;
}
$i++;
}
}
//文件名处理
if( !$file_name ){
$file_name = date( 'YmdHis', time() );
}
//网页下载
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
// header('Content-Disposition: attachment;filename='."$file_name");
header('Content-Disposition:inline;filename='.$file_name.'.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
$objWriter = PHPExcel_IOFactory::createWriter($obj, 'Excel2007');
$objWriter->save('php://output');
exit;
}
public function get_excel_demo()
{
$this->class_get_excel1( $this->reward_employee_log,['reward_order_id','employee_user_id','create_date'],'还不是美滋滋','sheet2','create_date','2017-09-04 16:47:00','2017-09-08 19:59:18' );
}
上面的方法有点儿封装过头了,有些场景我们需要去导出的数据进行判断导出,比如说:一般数据表里面的 sex 字段我们经常用 1 表示男 2 表示女。如果我们没有加以判断就导出的话,管理员看到表格后难免会摸不着头脑,所以建议 Excel 的数据和表头都放到形参上面,在调用的时候赋值实参上就行了。
/**
* @author Hiking,Lin
* @attention 需要自己引入PHPExcel类 和 IOFactory.php文件。
* @attention 数据处理机制基于WordPress 请替换为自己框架处理方式。
* @attention 标题默认拿的字段备注信息! 没有则为null
* @attention 标题默认字号为size:10 字体为微软雅黑
* @param $file_name 导出excel文件名,没有设置则随机生成
* @param $sheet $sheet的名字 没有设置则为 sheet1
* @param $excel_title excel的表头标题
* @param $data_res excel的表格内容
*/
public function class_get_excel2( $file_name = '', $sheet='', $excel_title, $data_res){
// 实例化 PHPExcel 类
$obj = new PHPExcel();
$objSheet = $obj->getActiveSheet();
$objSheet->getDefaultStyle()->getAlignment()->setVertical(PHPExcel_Style_Alignment::VERTICAL_CENTER)->setHorizontal(PHPExcel_Style_Alignment::HORIZONTAL_CENTER);//设置excel文件默认水平垂直方向居中
$objSheet->getStyle("A1:Z1")->getFont()->setSize(16)->setBold(true); //设置第二行字体大小和加粗
$objSheet->getDefaultStyle()->getFont()->setSize(10)->setName("微软雅黑"); //设置默认字体大小和格式
// 第一行的默认高度
$obj->getActiveSheet()->getRowDimension('1')->setRowHeight(30);
//横向单元格标识
$cellName = array('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 = empty( $sheet ) ? 'sheet1' : $sheet;
$obj->getActiveSheet(0)->setTitle( $sheet ); //设置sheet名称
$_row = 1; //设置纵向单元格标识
if( $excel_title ) {
$_cnt = count( $excel_title );
$obj->getActiveSheet(0)->mergeCells('A'.$_row.':'.$cellName[$_cnt-1].$_row); //合并单元格
$obj->setActiveSheetIndex(0)->setCellValue('A'.$_row, '数据导出:'.date('Y-m-d H:i:s')); //设置合并后的单元格内容
//垂直居中
// $obj->getActiveSheet()->getStyle('A')->getAlignment()->setVertical( PHPExcel_Style_Alignment::VERTICAL_CENTER );
$_row++;
$i = 0;
foreach( $excel_title AS $v ){ //设置列标题
$obj->setActiveSheetIndex(0)->setCellValue($cellName[$i].$_row, $v);
$i++;
}
$_row++;
}
//填写数据
if( $data_res ){
$i = 0;
foreach($data_res AS $_v){
$j = 0;
foreach($_v AS $_cell){
$obj->getActiveSheet(0)->setCellValue( $cellName[ $j ] . ( $i + $_row ), $_cell);
$j++;
}
$i++;
}
}
//文件名处理
if( !$file_name ){
$file_name = date( 'YmdHis', time() );
}
//网页下载
// Redirect output to a client’s web browser (Excel2007)
header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
// header('Content-Disposition: attachment;filename='."$file_name");
header('Content-Disposition:inline;filename='.$file_name.'.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
$objWriter = PHPExcel_IOFactory::createWriter($obj, 'Excel2007');
$objWriter->save('php://output');
exit;
}
调用 Demo
public function class_get_excel()
{
// 模拟数据 $field 控制需要的数据字段和对应的表头信息
$field = [];
$table_name = $this->reward_employee_log;
$sql = "show full columns from $table_name";
$start_field_name = 'create_date';
$start_date = '2017-09-04 16:47:00';
$end_date = '2017-09-08 19:59:18';
$res = $this->wpdb->get_results( $sql,ARRAY_A );
//计算字段名
if ( count( $field ) < 1 ) {
$field = '*';
// $title单元格标题头 默认拿的字段的注释
$excel_title = array_column( $res,'Comment' );
}else{
$excel_arr = array_column( $res,'Comment','Field' );
foreach ($field as $key => $value) {
$excel_title[] = $excel_arr[$value];
}
$field = join( ',',$field );
}
// 如果字段没有备注信息 这里可以给表头写上自定义的名称
$excel_title = ['id','name','xxxx','xxxxx'];
// 判断时间筛选是否存在
if ( empty( $start_field_name ) || empty( $start_date ) || empty( $end_date ) ) {
$data_sql = "SELECT $field FROM $table_name";
}else{
$data_sql = "SELECT $field FROM $table_name WHERE 1 AND $start_field_name BETWEEN '{$start_date}' AND '{$end_date}' ";
}
// 拿到表格数据 这里可以根据自己需求去遍历重新赋值
$data_res = $this->wpdb->get_results( $data_sql,ARRAY_A );
// foreach ($data_res as $value) {
// do something you like
// }
$this->class_get_excel2( '我的excel', 'sheet1', $excel_title , $data_res );
}
GG