YII 2 프레임 워 크 에서 excel 표 내 보 내기 방법 상세 설명
20498 단어 yii 2 프레임 워 크엑셀 내 보 내기
표 의 가 져 오기 내 보 내기 는 우리 가 일상적인 개발 에서 자주 볼 수 있 는 기능 이다.마침 최근 프로젝트 에서 표 출력 에 관 한 기능 을 했 고 그 전에 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.결과여기까지 거의 모든 임 무 를 완수 했다!
총결산
이상 은 이 글 의 전체 내용 입 니 다.본 논문 의 내용 이 여러분 의 학습 이나 업무 에 어느 정도 도움 이 되 기 를 바 랍 니 다.궁금 한 점 이 있 으 시 면 댓 글 을 남 겨 주 셔 서 저희 에 대한 지지 에 감 사 드 립 니 다.