/**
* 万级数据导出公用方法【复杂版,适用于重量级数据导出,1万条以内,导出格式为xls,大于1万条数据,使用csv格式】
* @param $type 导出记录类型
* @param $exportDescr 导出记录条件说明
* @param $xlsTitle 导出的标题
* @param $fileName 导出的文件名称
* @param $items_count 导出的数据总量
* @param $xlsCell 导出的内容标题及样式设定
* @param $params 查询数据所需的基本条件
* @param $per_write 每次查询并写入的数据量,默认为1000条
* @author wangdb
*/
function exportPublicMultiple($type, $exportDescr, $xlsTitle, $fileName, $items_count, $xlsCell, $params, $per_write = ‘1000’)
{
$dataNum = $items_count; // 总数据条数
$cellNum = count($xlsCell); // 总的数据列数
$filter = $params[‘filter’]; // 查询的基本条件
$start_date = (isset($params[‘start_date’]) && $params[‘start_date’])?$params[‘start_date’]:”; // 查询的开始时间范围
$end_date = (isset($params[‘end_date’]) && $params[‘end_date’])?$params[‘end_date’]:”; // 查询的结束时间范围
if($dataNum <= 10000){
// 创建文件对象
$resultPHPExcel = new \PHPExcel();
$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’);
// 导出文件的基本信息
$resultPHPExcel->getProperties()->setCreator(“qlcx”); // 创建人
$resultPHPExcel->getProperties()->setLastModifiedBy(“qlcx”); // 最后修改人
$resultPHPExcel->getProperties()->setTitle($xlsTitle); // 标题
$resultPHPExcel->getProperties()->setSubject($xlsTitle); // 题目
// 第一行内容居中
$resultPHPExcel->getActiveSheet()->getStyle(“A1:”.$cellName[$cellNum-1].“1”)->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::VERTICAL_CENTER);
// 设置第一行的内容信息
for($i=0; $i<$cellNum; $i++){
// 填充第一行内容
$resultPHPExcel->getActiveSheet()->setCellValue($cellName[$i].‘1’, $xlsCell[$i][1]);
// 设置单元格的宽度
$resultPHPExcel->getActiveSheet()->getColumnDimension($cellName[$i])->setWidth($xlsCell[$i][2]);
}
// 主内容居中显示
$resultPHPExcel->getActiveSheet()->getStyle(“A2:”.$cellName[$cellNum-1].($dataNum+1))->getAlignment()->setHorizontal(PHPExcel_Style_Alignment::VERTICAL_CENTER);
// 将数据添加进去
$times = $last_num = 0;
// 前几次查询的数据条数
$times = floor($dataNum/$per_write);
// 最后一次查询的数据条数
$last_num = $dataNum – $times*$per_write;
for($a=0;$a<=$times;$a++){
$start = $per_write*$a;
if($a == $times){
$per_write = $last_num;
}
// 当开始位置大于或等于最大导出数量的,由于skip的位置是从0开始的,所以,此时就不能再进行查询了,因为找不到对应的数据了
if($start < $dataNum){
switch ($type){
case 1:
$xlsData = ”;// 从$start位置开始查,每次查询$per_write条数据
break;
default:break;
}
// 最大的执行次数
$max = $start+$per_write;
$b = 0;
for($i=$start;$i<$max;$i++){
$order = array();
if($type == 1){
// 如果获取到的数据是对象的话,则需要进行转化,抓化成数组,方法可以自己定义
$order = \Utils::objectToArray($xlsData[$b]);
}else{
$order = $xlsData[$b][‘attributes’]; // 如果可以直接获取数组形式的更好
}
// 在此,可以对数据进行二次处理,此处省略~~~
for($j=0;$j<$cellNum;$j++){
// 填写内容
$resultPHPExcel->getActiveSheet()->setCellValue($cellName[$j].($i+2),$order[$xlsCell[$j][0]]);
}
$b++;
}
unset($xlsData); // 将已经写到excel中的数据存储变量销毁,释放内存占用
ob_start(); // 开始当前缓存
ob_flush(); // 输出当前缓冲
}
}
$desc = ‘导出’.$type.‘,导出量为’.$dataNum.‘条,导出条件为:“’.$exportDescr.‘”’;
$res = \EditorActionRecord::AddActionRecord($desc); // 添加到操作记录里面
header(‘pragma:public’);
header(‘Content-type:application/vnd.ms-excel;charset=utf-8;name=”‘.$xlsTitle.‘.xls”‘);
header(“Content-Disposition:attachment;filename=.$fileName.xls”);//attachment新窗口打印inline本窗口打印
$objWriter = \PHPExcel_IOFactory::createWriter($resultPHPExcel, ‘Excel5’);
$objWriter->save(‘php://output’);
exit();
}else{
// 数据量大的时候,改用csv格式导出
$real_name = $fileName.“.csv”;
header ( ‘Content-Type: application/vnd.ms-excel’ );
header ( ‘Content-Disposition: attachment;filename=’.$real_name );
header ( ‘Cache-Control: max-age=0’ );
set_time_limit(0);
ini_set(“max_execution_time”, 0);
// 打开PHP文件句柄,php://output 表示直接输出到浏览器
$file = fopen(‘php://output’,“a”);
// 填写标题内容,将中文标题转换编码,否则乱码
foreach ($xlsCell as $key=>$val){
$tit[]=iconv(‘UTF-8’, ‘GB2312//IGNORE’,$val[1].“\t”);
if($key == $cellNum-1){
// 用记事本打开的时候,添加上换行符,样式会更好看一点
$tit[] = “\r\n”;
}
}
// 将标题名称通过fputcsv写到文件句柄
fputcsv($file,$tit);
// 将数据添加进去
$times = $last_num = 0;
// 前几次查询的数据条数
$times = floor($dataNum/$per_write);
// 最后一次查询的数据条数
$last_num = $dataNum – $times*$per_write;
for($a=0;$a<=$times;$a++){
$start = $per_write*$a;
if($a == $times){
$per_write = $last_num;
}
// 当开始位置大于或等于最大导出数量的,由于skip的位置是从0开始的,所以,此时就不能再进行查询了,因为找不到对应的数据了
if($start < $dataNum){
switch ($type){
case 1:
$xlsData = ”; // 从$start位置开始查,每次查询$per_write条数据
break;
default:break;
}
// 最大的执行次数
$max = $start+$per_write;
$b = 0;
for($i=$start;$i<$max;$i++){
$order = array();
if($type == 1){
// 如果获取到的数据是对象的话,则需要进行转化,抓化成数组,方法可以自己定义
$order = \Utils::objectToArray($xlsData[$b]);
}else{
$order = $xlsData[$b][‘attributes’]; // 如果可以直接获取数组形式的更好
}
// 在此,可以对数据进行二次处理,此处省略~~~
for($j=0;$j<$cellNum;$j++){
// 填写内容,前面添加制表符,以规范样式
$tarr[]=iconv(‘UTF-8’, ‘GB2312//IGNORE’,$order[$xlsCell[$j][0]].“\t”);
// 用记事本打开的时候,添加上换行符,样式会更好看一点
if($j == $cellNum-1){
$tarr[] = “\r\n”;
}
}
// 将已经写到csv中的数据存储变量销毁,释放内存占用
fputcsv($file,$tarr);
unset($tarr);
$b++;
}
unset($xlsData); // 将已经写到csv中的数据存储变量销毁,释放内存占用
ob_flush(); // 输出当前缓冲
flush();
}
}
$desc = ‘导出’.$type.‘,导出量为’.$dataNum.‘条,导出条件为:“’.$exportDescr.‘”’;
$res = \EditorActionRecord::AddActionRecord($desc);
fclose($file);
exit();
}
}