php 封装的导出Excel的小工具
php通过composer安装phpoffice,composer中添加如下require
"require": {
"php": ">=5.6.0",
"topthink/framework": "5.1.*",
"topthink/think-captcha": "^2.0",
"phpoffice/phpspreadsheet": "^1.6",
"qcloud/cos-sdk-v5": "^1.3",
"hooklife/thinkphp5-wechat": "^1.1",
"qcloudsms/qcloudsms_php": "^0.1.4"
},
$list_export = '通过数据库查询出来的数据';
foreach ($list_export as $k => $v) {
$list_export[$k]['student_name'] = (new StudentModel())->getById($v['student_id'])['student_name'];
$list_export[$k]['course_name'] = (new CourseModel())->getById($v['course_id'])['course_name'];
$list_export[$k]['class_name'] = (new ClassModel())->getById($v['class_id'])['class_name'];
$list_export[$k]['pa'] = (new AdminModel())->getById($v['check_pa'])['nickname'];
$list_export[$k]['teacher_name'] = (new AdminModel())->getById($v['class_teacher'])['nickname'];
$list_export[$k]['school_name'] = (new SchoolModel())->getById($v['school_id'])['school_name'];
$list_export[$k]['check_status'] = $check_work_state[$v['status']];
}
$arr = [
'A' => '校区|school_name|20 ',
'B' => '班级名称|class_name|20',
'C' => 'PA|pa|20',
'D' => '学员姓名|student_name|20',
'E' => '课程|course_name|20',
'F' => '上课老师|teacher_name|20',
'G' => '在读状态|check_status|20',
'H' => '课时|class_hour|20',
'I' => '课销|price|20',
];
export_excel($arr, $list_export, '', '课销统计.xlsx', 1);
以上代码中的$arr就是一个对应的Excel中的列的名称,对应数据库中的名字,还有就是每个cell的宽度,如果想要设置更多属性可以模仿在宽度后面增加|分割新字段。list_export就是要导出的数据。以下关键在于export_excel 这个函数。
use PhpOffice\PhpSpreadsheet\Spreadsheet;//使用前先use下命名空间
function export_excel($arr = [], $data = [], $file_dir = './logs', $file_name = '', $is_download = 0)
{
try {
$spreadsheet = new Spreadsheet();
$temp = $spreadsheet->setActiveSheetIndex(0);
$temp1 = $spreadsheet->getActiveSheet();
$writer = \PhpOffice\PhpSpreadsheet\IOFactory::createWriter($spreadsheet, 'Xlsx');
$i = 1;
$data1 = [[]];
foreach ($data as $k => $v) {
$data1[] = $data[$k]; //为表头增加一次循环
}
$data = $data1;
foreach ($data as $k => $v) {
foreach ($arr as $kk => $vv) {
$val_arr = explode('|', $vv);
$new_key = $kk . $i;
if ($i == 1) {
$temp->setCellValue($new_key, $val_arr[0]);
} else {
$temp1->setCellValue($new_key, $v[$val_arr[1]]);
}
$temp1->getColumnDimension($kk)->setWidth($val_arr[2]);
}
$i++;
}
//设置每一个标题列的宽度
$file_name = ($file_name == '' ? time() . rand(1000, 90000) . '.xlsx' : $file_name);
$save_file = $file_dir . $file_name;
ob_end_clean();
$writer->save($save_file);
if ($is_download) {
//以只读和二进制模式打开文件
$file = fopen($save_file, "rb");
//告诉浏览器这是一个文件流格式的文件
Header("Content-type: application/octet-stream");
//请求范围的度量单位
Header("Accept-Ranges: bytes");
//Content-Length是指定包含于请求或响应中数据的字节长度
Header("Accept-Length: " . filesize($save_file));
//用来告诉浏览器,文件是可以当做附件被下载,下载后的文件名称为$file_name该变量的值。
Header("Content-Disposition: attachment; filename=" . $file_name);
//读取文件内容并直接输出到浏览器
echo fread($file, filesize($save_file));
fclose($file);
exit ();
} else {
return commonArr(1, '生成文件成功', ['name' => $save_file]);
}
} catch (\Exception $exception) {
return commonArr(0, $exception->getMessage());
}
对于这个函数的优点就是通过循环来避免之前的挨个cell的设置,太麻烦了,可以通过is_download配置直接导出数据还是生成文件,然后把文件名返回给前端,这也不是多好的函数,只当是一个工具,如果分享给大家。