- 常规的php excel包需要所有的数据先拿到然后才能生成excel, 当生成超大数据量的excel文件时这显然是会造成内存溢出的,所以考虑使用让PHP边写入输出流边让浏览器下载的形式来完成需求。
我们通过如下的方式写入PHP输出流
set_time_limit(0);
ini_set("memory_limit", "512M");
$fp = fopen('php://output', 'a');
fputs($fp, 'strings');
....
....
fclose($fp)
封装方法
public function ExcelFun($searchName=[],$csvFileName,$columns,$Field,$accessNum = 0,$perSize=500000)
{
if(empty($csvFileName) ||empty($columns)||empty($Field)){
return json_encode(['status'=>0,'msg'=>"参数有误!"]);
}
set_time_limit(0);
ini_set("memory_limit", "512M");
$csvFileName = $csvFileName . '.csv';
$pages = ceil($accessNum / $perSize);
header('Content-Description: File Transfer');
header('Content-Type: application/vnd.ms-excel');
header('Content-Disposition: attachment; filename="'. $csvFileName .'"');
header('Expires: 0');
header('Cache-Control: must-revalidate');
header('Pragma:public');
$fp = fopen('php://output', 'a');
mb_convert_variables('GBK', 'UTF-8', $columns);
fputcsv($fp, $columns);
for($i = 1; $i <= $pages; $i++) {
$accessLog = $this->getArticleAccessLog($searchName,$perSize,$lastId);
foreach($accessLog as $access) {
$rowData = [];
foreach ($Field as $key => $value) {
$rowData[] = $access[$value];
}
mb_convert_variables('GBK', 'UTF-8', $rowData);
fputcsv($fp, $rowData);
}
unset($accessLog);
ob_flush();
flush();
}
fclose($fp);
exit();
}
调用封装
public function RecordWorkersExcel(){
$searchName = input('parson_name');
$projectName = input('projectName');
$team_personname = input('team_personname');
$where = '';
$point = 0;
if($searchName){
$point += 1;
$where .= " parson_name like '%".$searchName."%' ";
}
if($projectName){
if($point){
$where .= " AND projectName like '%".$projectName."%' ";
}else{
$where .= " projectName like '%".$projectName."%'";
}
}
if($team_personname){
if($point){
$where .= " AND team_personname like '%".$team_personname."%'";
}else{
$where .= " team_personname like '%".$team_personname."%'";
}
}
$search = [
'searchName' => $searchName,
'projectName' => $projectName,
'team_personname' => $team_personname,
];
$table = "laval_record_workers";
$count = Db::connect('db_config_laval')->table($table)->where($where)->count();
$csvFileName = "记工记录导出";
$Explain = [
'ID','姓名','用户手机号','负责人','工地名称','工地编号','班组名称','班组编号','类型','数量','记录时间','审核通过(1/0)','备注'
];
$Field = [
'id','parson_name','cell_phone','team_personname','projectName','projectCode','team_name','team_code','tit_id','num','current_time','is_state','content'
];
return $this->ExcelFun($searchName,$csvFileName,$Explain,$Field,$accessNum=1,$perSize=500000);
}
业务流程根据自己的项目需要
public function getArticleAccessLog($searchName,$num,$lastId=0){
$table = "laval_record_workers";
$list = Db::connect('db_config_laval')->table($table)
->where('parson_name','like','%'.$searchName['searchName'].'%')
->where('projectName','like','%'.$searchName['projectName'].'%')
->where('team_personname','like','%'.$searchName['team_personname'].'%')
->order('id','desc')
->limit($lastId,$num)
->select();
foreach ($list as $key => &$value){
$str = "workers_" . $value['tit_id'];
if(Config($str)){
$value['tit_id'] = COnfig($str);
}else{
$value['tit_id'] = '未配置';
}
$value['is_state'] = $value['is_state'] == 1 ? "是":(empty($value['is_state'])?"等待审核":"否");
$table = "laval_team";
$team = Db::connect('db_config_laval')->table($table)
->where(['id'=>$value['team_id'],'team_code'=>$value['team_code']])
->find();
$value['team_name'] = $team['team_name'];
$value['PersonPhone'] = $team['cell_phone'];
}
return $list;
}