【原创】万级数据导出公用方法

【原创】万级数据导出公用方法

// 导出的内容标题及样式设定:第一个参数代表是数据中的字段,第二个参数代表是标题,第三个参数代表是列宽度
$xlsCell  =array(
     array(‘editor_id’,‘管理员ID’,’10’),
     array(‘name’,‘管理员名称’,’15’),
     array(‘type’,‘操作类型’,’15’),
     array(‘desc’,‘操作详情’,’50’),
     array(‘user_id’,‘操作对象’,’15’),
     array(‘create_date’,‘操作时间’,’20’)
);
/**
 * 万级数据导出公用方法【复杂版,适用于重量级数据导出,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();
    }
}

发表评论

电子邮件地址不会被公开。 必填项已用*标注

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据