YII 2 프레임 워 크 에서 excel 표 내 보 내기 방법 상세 설명

머리말
표 의 가 져 오기 내 보 내기 는 우리 가 일상적인 개발 에서 자주 볼 수 있 는 기능 이다.마침 최근 프로젝트 에서 표 출력 에 관 한 기능 을 했 고 그 전에 TP 를 사용 할 때 도 했 기 때문에 이번 기능 이 비교적 다양한 기 회 를 틈 타 정리 해 야 나중에 필요 할 때 나 필요 한 친구 들 이 참고 학습 을 할 수 있다 고 생각 했다.다음은 더 이상 말 하지 않 겠 다.상세 한 소 개 를 살 펴 보 자.
본 고 는 YII 2 프레임 워 크 를 바탕 으로 개 발 된 것 으로 서로 다른 프레임 워 크 는 변경 이 필요 할 수 있다
일반 엑셀 형식 표 출력
먼저 가장 일반적인.xls 형식의 표를 내 보 냅 니 다.우선 표 가 사이트 에 표시 되 는 효 과 를 살 펴 보 겠 습 니 다.

여기 서 전체 표 가 모두 7 열 이라는 것 을 볼 수 있다.다음은 코드 의 실현 을 살 펴 보 겠 습 니 다.
1.controller 파일

//    

public function actionStatistics(){
 //    
 ini_set("memory_limit", "2048M");
 set_time_limit(0);

 //    ID
 $id = Yii::$app->user->identity->getId();

 //          
 $user = Employee::find()->where(['id'=>$id])->one();

 //        (  ,  ID   ,            )
 $params = Yii::$app->request->get();
 $objectPHPExcel = new \PHPExcel();

 //        
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('A1', '    ');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('B1', '  ');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('C1', '  ');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('D1', '   ');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('E1', '  (  -  )');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('F1', '   (  /  )*100%');
 $objectPHPExcel->setActiveSheetIndex()->setCellValue('G1', 'ARPU ');

 //   recharge  model   statistics       
 $data = Recharge::statistics($params);

 //           
 $n = 2;
 foreach ($data as $v){
 $objectPHPExcel->getActiveSheet()->setCellValue('A'.($n) ,$v['company_name']);
 $objectPHPExcel->getActiveSheet()->setCellValue('B'.($n) ,$v['company_cost']);
 $objectPHPExcel->getActiveSheet()->setCellValue('C'.($n) ,$v['cost']);
 $objectPHPExcel->getActiveSheet()->setCellValue('D'.($n) ,$v['num']);
 $objectPHPExcel->getActiveSheet()->setCellValue('E'.($n) ,$v['gross_margin']);
 $objectPHPExcel->getActiveSheet()->setCellValue('F'.($n) ,$v['gross_profit_rate']);
 $objectPHPExcel->getActiveSheet()->setCellValue('G'.($n) ,$v['arpu']);
 $n = $n +1;
 }
 ob_end_clean();
 ob_start();
 header('Content-Type : application/vnd.ms-excel');

 //          
 header('Content-Disposition:attachment;filename="      '.date("YmdHis").'.xls"');

 //  .xls      Excel5,     .xlsx    Excel2007
 $objWriter= \PHPExcel_IOFactory::createWriter($objectPHPExcel,'Excel5');
 $objWriter->save('php://output');
 ob_end_flush();

 //      
 unset($data);
}
2.model 파일

 <?php
 namespace app\models;//model      
 //     yii arrayhelper
 use yii\helpers\ArrayHelper;
 use Yii;
 class Recharge extends \yii\db\ActiveRecord
 {
 //excel      
 const EXCEL_SIZE = 10000;
 
 //    
 public static function statistics($params){

 //      
 if(empty($params['min'])){
 $date_max = date("Y-m-d",strtotime("-1 day"));
 $date_min = date("Y-m-d",strtotime("-31 day"));
 }else{
 $date_min = $params['min'];
 $date_max = $params['max'];
 }
 $where = '';
 $where .= '(`issue_date` BETWEEN '.'\''.$date_min.'\''.' AND '.'\''.$date_max.'\')';

 //      
 $sql = 'select
 article.company_id,
 article.cost,
 article.company_cost
 from article WHERE article.status=2 AND '.$where;
 $article = Article::findBySql($sql)->asArray()->all();
 $article = ArrayHelper::index($article,null,'company_id');
 $companys = [];

 foreach ($article as $key=>$v){
 if(empty($key)){
 continue;
 }else{
 $number = count($v);
 $company = Company::find()->where(['id'=>$key])->select('name')->one();
 $company_name = $company['name'];
 $cost = 0;
 $company_cost = 0;
 foreach ($v as $n){
 $cost += $n['cost'];
 $company_cost += $n['company_cost'];
 }
 if($company_cost == 0){
 $company_cost =1;
 }

 //    ,                    
 $companys[] = [
 //   
 'company_name' => $company_name,

 //  
 'company_cost' => $company_cost,

 //  
 'cost' => $cost,

 //   
 'num' => $number,

 //  
 'gross_margin' => $company_cost-$cost,

 //   
 'gross_profit_rate' => round(($company_cost-$cost)/$company_cost*100,2).'%',

 //ARPU 
 'arpu' => round($company_cost/$number,2),
 ];
 }
 }
 return $companys;
 }
}
최종 내 보 내기 효과(셀 크기 내 보 내기 후 조정)는 웹 페이지 에 표 시 된 기본 과 같 습 니 다.

빅 데이터 시트 내 보 내기
이때 사장 이 말 했다.우 리 는 총 화 된 데이터 만 볼 수 없고 상세 한 데이터 도 유도 하 는 것 이 좋 겠 다.사장 님 이 말씀 하 셨 으 니 하 세 요.아니면 첫 번 째 방법 으로 하 시 겠 습 니까?그 결과 phop 이 무 너 졌 다 는 것 을 알 렸 습 니 다.다시 한 번 알 아 보 니 바이트 가 초과 되 었 습 니 다.php 프로필 열기 php.ini

memory_limit = 128M
기본 메모리 가 128 M 에 이 르 렀 으 니 충분 할 것 같 습 니 다.그래서 내 가 데이터 베 이 스 를 열 어 보 니,허!
83 만 건 에 가 까 운 데 이 터 를 조회 하고 내 보 내 면 문제 가 생 길 수 있 잖 아!어 떡 하지?그래서 구 글 을 해 보 니 빅 데이터(2 만 개 이상)내 보 내기 가.csv 형식 이 좋 더 라 고요.쓸데없는 말 말고 코드 를 바로 달 아 라.
1.controller 파일

//    

public function actionInventory(){
 ini_set("memory_limit", "2048M");
 set_time_limit(0);
 $id = Yii::$app->user->identity->getId();
 $user = Employee::find()->where(['id'=>$id])->one();
 $params = Yii::$app->request->get();
 
 //   ,   recharge  model    inventory       
 $data = Recharge::inventory($params);
 
 //        
 $fileName = iconv('utf-8', 'gbk', '       '.date("Y-m-d"));
 
 //    
 $headlist = array('   ','  ID','    ','  ','      ','  ','    ','    ','    ','    ','    ','  ','   ','          ','    ');
 header('Content-Type: application/vnd.ms-excel');
 
 //       
 header('Content-Disposition: attachment;filename="'.$fileName.'.csv"');
 header('Cache-Control: max-age=0');
 
 //  PHP    ,php://output           
 $fp = fopen('php://output', 'a');
 
 //  Excel    
 foreach ($headlist as $key => $value) {
 //CSV Excel  GBK  ,     ,    
 $headlist[$key] = iconv('utf-8', 'gbk', $value);
 }
 
 //     fputcsv      
 fputcsv($fp, $headlist);
 
 //  $limit ,      buffer,    ,     
 $limit = 100000;
 
 //      ,     
 foreach ($data as $k => $v) {
 //      buffer,            
 if ($k % $limit == 0 && $k!=0) {
 ob_flush();
 flush();
 }
 $row = $data[$k];
 foreach ($row as $key => $value) {
 $row[$key] = iconv('utf-8', 'gbk', $value);
 }
 fputcsv($fp, $row);
 }
}
2.model 파일(이 부분 은 제 가 처리 해 야 할 부분 이 너무 많아 서 일부 코드 만 선 택 했 습 니 다).데이터 부분 을 조회 할 때 찾 아야 할 데이터 가 많 기 때문에 제 가 전에 쓴 Mysql 빅 데이터 조회 처리 에 관 한 글 과 결합 하여 볼 수 있 습 니 다.
//목록 내 보 내기

public static function inventory($params){
 //      
 if(!empty($params['min']) && !empty($params['max'])){
 $ti = strtotime($params['max'])+3600*24;
 $max = date('Y-m-d',$ti);
 $time = $params['min'].'-'.$params['max'];
 $date_min = $params['min'];
 $date_max = $max;
 }else{
 $date_max = date('Y-m-d');
 $date_min = date('Y-m-d',strtotime("-31 day"));
 $time = $date_min.'-'.$date_max;
 }
 //    
 if($params['state'] == 1){
 $where = '';
 $where .= ' AND (`issue_date` BETWEEN '.'\''.$date_min.'\''.' AND '.'\''.$date_max.'\')';
 $map = 'select
  company.name,
  article.id,
  article.title,
  media.media_name,
  article.status,
  article.created,
  article.audit_at,
  article.issue_date,
  article.back_date,
  article.finance_status,
  article.cost,
  article.company_cost,
  media.is_advance
  from article
  LEFT JOIN custom_package ON custom_package.id = article.custom_package_id
  LEFT JOIN `order` ON custom_package.order_id = `order`.`id`
  LEFT JOIN company ON company.id = article.company_id
  LEFT JOIN media ON media.id = article.media_id
  where article.status=2 and `order`.package=0'.$where;
 //         ,  asArray                     ,            (  :                      )
 $list1 = Article::findBySql($map)->asArray()->all();
 $where2 = '';
 $where2 .= ' AND (`issue_date` BETWEEN '.'\''.$date_min.'\''.' AND '.'\''.$date_max.'\')';
 $where2 .= ' AND (`back_date` > \''.$date_max.'\')';
 $map2 = 'select
  company.name,
  article.id,
  article.title,
  media.media_name,
  article.status,
  article.created,
  article.audit_at,
  article.issue_date,
  article.back_date,
  article.finance_status,
  article.cost,
  article.company_cost,
  media.is_advance
  from article
  LEFT JOIN custom_package ON custom_package.id = article.custom_package_id
  LEFT JOIN `order` ON custom_package.order_id = `order`.`id`
  LEFT JOIN company ON company.id = article.company_id
  LEFT JOIN media ON media.id = article.media_id
  where article.status=3 and `order`.package=0 '.$where2;
 //         
 $list2 = Article::findBySql($map2)->asArray()->all();
 $where3 = '';
 $where3 .= ' AND (`issue_date` BETWEEN '.'\''.$date_min.'\''.' AND '.'\''.$date_max.'\')';
 $map3 = 'select
  company.name,
  article.id,
  article.title,
  media.media_name,
  article.status,
  article.created,
  article.audit_at,
  article.issue_date,
  article.back_date,
  article.finance_status,
  article.cost,
  article.company_cost,
  media.is_advance
  from article
  LEFT JOIN custom_package ON custom_package.id = article.custom_package_id
  LEFT JOIN `order` ON custom_package.order_id = `order`.`id`
  LEFT JOIN company ON company.id = article.company_id
  LEFT JOIN media ON media.id = article.media_id
  where article.status=5 '.$where3;
 //         
 $list3 = Article::findBySql($map3)->asArray()->all();
 $list4 = ArrayHelper::merge($list1,$list2);
 $list = ArrayHelper::merge($list4,$list3);
 }
 //                 
 if(!empty($list)){
 foreach ($list as $key => $value){
 //    
 $inventory[$key]['company_name'] = $value['name'];
 //  ID
 $inventory[$key]['id'] = $value['id'];
 //    
 $inventory[$key]['title'] = $value['title'];
 //  
 $inventory[$key]['media'] = $value['media_name'];
 //    
 $inventory[$key]['time'] = $time;
 //  
 switch($value['status']){
 case 2:
  $inventory[$key]['status'] = '   ';
  break;
 case 3:
  $inventory[$key]['status'] = '   ';
  break;
 case 5:
  $inventory[$key]['status'] = '    ';
  break;
 }
 //    
 $inventory[$key]['created'] = $value['created'];
 //    
 $inventory[$key]['audit'] = $value['audit_at'];
 //    
 $inventory[$key]['issue_date'] = $value['issue_date'];
 //    
 $inventory[$key]['back_date'] = $value['back_date'];
 //    
 switch($value['finance_status']){
 case 0:
  $inventory[$key]['finance_status'] = '     ';
  break;
 case 1:
  $inventory[$key]['finance_status'] = '   ';
  break;
 case 2:
  $inventory[$key]['finance_status'] = '     ';
  break;
 case 3:
  $inventory[$key]['finance_status'] = '     ';
  break;
 case 4:
  $inventory[$key]['finance_status'] = '   ';
  break;
 case 5:
  $inventory[$key]['finance_status'] = '   ';
  break;
 case 6:
  $inventory[$key]['finance_status'] = '     ';
  break;
 }
 //  
 $inventory[$key]['cost'] = $value['cost'];
 //   
 $inventory[$key]['company_cost'] = $value['company_cost'];
 //     
 switch($value['is_advance']){
 case 0:
  $inventory[$key]['is_advance'] = ' ';
  break;
 case 1:
  $inventory[$key]['is_advance'] = ' ';
  break;
 case 2:
  $inventory[$key]['is_advance'] = '  ';
  break;
 }
 //    
 switch($params['state']){
 case 1:
  $inventory[$key]['order_type'] = '           ';
  break;
 case 2:
  $inventory[$key]['order_type'] = '           ';
  break;
 case 3:
  $inventory[$key]['order_type'] = '               ';
  break;
 case 4:
  $inventory[$key]['order_type'] = '                 ';
  break;
 case 5:
  $inventory[$key]['order_type'] = '    ';
  break;
 }
 }
 }else{
 $inventory[0]['company_name'] = '     ';
 }
 return $inventory;
}
3.결과 내 보 내기

내 보 내기 수량

내 보 낸 파일

기본적으로 전체 과정 을 2~4 초 안에 처리 할 수 있다.
3.병합 셀
사장 님 이 잘 한 것 같 아서 충전 통 계 를 내 보 내 는 김 에 내 가 이렇게 많은 데 이 터 를 처리 한 사람 이 라 고 생각 하 세 요.아직 1 분 에 해결 할 일이 아 닙 니까?자,원형 도

푸,피투성이 가 되 어 말 을 다 했 으 니 하 자.할 때 나 는 이번 도 출 은 주로 단원 격 합병 문 제 를 해결 해 야 한 다 는 것 을 발견 했다.조사 자 료 를 통 해 PHP 자체 가 단원 격 합병 을 실현 할 수 없다 는 것 을 알 게 되 었 기 때문에 나 는 phopexcel 을 통 해 실현 할 계획 이다.
PHPExcel 을 사용한다 면 기본 동작 은 이 렇 습 니 다.(A1 에서 E1 까지 통합)

$objPHPExcel->getActiveSheet()->mergeCells('A1:E1');
//       
$objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');
결실

아니면 이런 거.

$objPHPExcel->getActiveSheet()->mergeCells('A1:E4');
$objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');
결실

이렇게 하면 나의 요 구 를 만족 시 킬 수 없다.먼저 그것 은 하나의 합병 이다.그 다음 에 내 가 표시 하고 자 하 는 충전 금액 아래 의 유형 은 변화 할 것 이다.고정 적 으로 죽은 다음 에 매번 바 꿀 수 없다.그래서 이런 방법 을 포 기 했 습 니 다.
나중에 동료 들 의 도움 을 받 아 html 로 엑셀 을 저장 하 는 방법 을 시도 했다.
1.방법 파일(매일 정시 에 실행 해 야 하기 때문에 controller 층 에 쓰 지 않 았 습 니 다)

public function actionExcelRechargeStatistics(){

 //     excel  
 $filename = date('【     】('.date('Y-m-d').'  )').".xls";
 header("Content-Type: application/vnd.ms-execl");
 header("Content-Type: application/vnd.ms-excel; charset=utf-8");
 header("Content-Disposition: attachment; filename=$filename");
 header("Pragma: no-cache");
 header("Expires: 0");
 //    
 if(empty($params['min'])){
 $time = date('Y-m-d',strtotime("+1 day"));
 $where = ' created < \' '.$time.'\'';
 }else{
 $time = $params['min']+3600*24;
 $time_end = $params['max']+3600*24;
 $where = ' created <= \' '.$time_end.'\' AND created >= \''.$time.'\' ';
 }
 //      
 $recharge_type = Recharge::find()->asArray()->all();
 if(empty($recharge_type)){
 $rechargelist[0]= '';
 }else{
 $rechargelist = ArrayHelper::map($recharge_type,'id','recharge_name');
 }
 $rechargelist1 = $rechargelist;
 $count = count($rechargelist1);
 //  html         
 $excel_content = '<meta http-equiv="content-type" content="application/ms-excel; charset=utf-8"/>';
 $excel_content .= '<table border="1" style="font-size:14px;">';
 $excel_content .= '<thead>
   <tr>
   <th rowspan="2">ID</th>
   <th rowspan="2">    </th>
   <th colspan='.$count.'>    </th>
   <th rowspan="2">    </th>
   <th rowspan="2">    </th>
   <th rowspan="2">    </th>
   </tr>
   <tr>
  ';
 foreach ($rechargelist1 as $v => $t){
 $excel_content .= '<th colspan="1">'.$t.'</th>';
 }
 $excel_content .= '</tr>
  </thead>';
 //         
 $search = RechargeStatistics::find()->where($where)->asArray()->all();
 if(!empty($search)){
 foreach ($search as $key => $value){
 $search[$key]['recharge'] = unserialize($value['recharge']);
 }
 }
 //html      
 if(empty($search)){
 }else{
 foreach ($search as $k) {
 $excel_content .= '<td>'.$k['company_id'].'</td>';
 $excel_content .= '<td>'.$k['company_name'].'</td>';
 foreach ($rechargelist1 as $v=>$t){
 $price = 0;
 foreach ($k['recharge'] as $q=>$w){
  if($w['recharge_id'] == $v){
  $price = $w['price'];
  break;
  }
 }
 $excel_content .= '<td>'.$price.'</td>';
 }
 $excel_content .= '<td>'.$k['total'].'</td>';
 $excel_content .= '<td>'.$k['consume'].'</td>';
 $excel_content .= '<td>'.($k['total']-$k['consume']).'</td></tr>';
 }
 }
 $excel_content .= '</table>';
 echo $excel_content;
 die;
}
2.결과

여기까지 거의 모든 임 무 를 완수 했다!
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.

좋은 웹페이지 즐겨찾기