Heim >Backend-Entwicklung >PHP-Tutorial >Grafisches Code-Tutorial zum Exportieren von Excel-Tabellen im YII2-Framework
Vor kurzem habe ich das Yii-Framework von PHP studiert und es gefällt mir sehr gut. Als ich auf das Problem des Excel-Exports stieß, habe ich es studiert und den folgenden Artikel verfasst Die Informationen im YII2-Framework werden ausführlich durch Beispielcode vorgestellt.
Vorwort
Der Import und Export von Tabellen ist eine Funktion, auf die wir in der täglichen Entwicklung häufig stoßen, und ich habe sie kürzlich zufällig ausgeführt Projekt Lassen Sie uns über die Tabellenausgabefunktion sprechen. Ich habe sie bereits bei der Verwendung von TP verwendet. Daher dachte ich, ich würde diese Gelegenheit nutzen, um sie zu klären, damit sie bei Bedarf in Zukunft oder für Freunde bequem verwendet werden kann Wer es als Referenz und zum Lernen braucht, wird im Folgenden nichts anderes sagen. Schauen wir uns die ausführliche Einführung an:
Dieser Artikel wurde möglicherweise auf der Grundlage des YII2-Frameworks entwickelt zu ändern
1. Gewöhnliches Excel-Format Tabellenausgabe
Der erste ist der gebräuchlichste Tabellenexport im .xls-Format. Schauen wir uns zunächst den Anzeigeeffekt der Tabelle auf der Website an
Hier sieht man, dass die gesamte Tabelle insgesamt 7 Spalten hat. Schauen wir uns die Implementierung des Codes an.
1.Controller-Datei
//导出统计 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.Modelldatei
<?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; } }
Der endgültige Exporteffekt (die Zellengröße wurde nach dem Exportieren angepasst) ist im Wesentlichen derselbe wie auf der Webseite angezeigt.
2. Big-Data-Tabellenexport
Zu diesem Zeitpunkt sagte der Chef: „Wir.“ Wenn Sie nicht nur die Gesamtdaten betrachten können, exportieren Sie am besten auch die Detaildaten. Jetzt, wo der Chef gesprochen hat, tun Sie es. Ich folgte immer noch der ersten Methode, aber das Ergebnis zeigte mir, dass PHP abstürzte. Als ich es erneut versuchte, stellte ich fest, dass die Anzahl der geschriebenen Bytes überschritten wurde. Öffnen Sie die PHP-Konfigurationsdatei php.ini
memory_limit = 128M
und stellen Sie fest, dass der Standardspeicher auf 128 MB festgelegt wurde, was ausreichen sollte. Also habe ich die Datenbank geöffnet und einen Blick darauf geworfen, oh!
Das Abfragen und Exportieren von fast 830.000 Daten wird Probleme verursachen! Was soll ich tun, also habe ich es gegoogelt und festgestellt, dass es für den Export großer Datenmengen (mehr als 20.000 Elemente) am besten ist, sie im CSV-Format zu exportieren. Kein Unsinn, gehen Sie einfach zum Code
1.controller-Datei
//导出清单 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-Datei ( Da ich mich in diesem Teil mit zu viel befassen muss, habe ich nur einen Teil des Codes ausgewählt. Da viele Daten überprüft werden müssen, können Sie sie in Verbindung mit betrachten Der Artikel, den ich zuvor über die Verarbeitung von MySQL-Big-Data-Abfragen geschrieben habe
//Liste exportieren
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 🎜>
Exportnummer Exportierte Dateien Stellen Sie grundsätzlich sicher, dass der gesamte Vorgang 2–4 Sekunden dauert. Interne Verarbeitung abgeschlossen 3. Zellen zusammenführen
$objPHPExcel->getActiveSheet()->mergeCells('A1:E1'); // 表格填充内容 $objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');Ergebnis Oder so (A1 mit E4 zusammenführen)
$objPHPExcel->getActiveSheet()->mergeCells('A1:E4'); $objPHPExcel->getActiveSheet()->setCellValue('A1','The quick brown fox.');Ergebnisse Dies entspricht nicht meinen Anforderungen. Zweitens wird der Aufladebetrag, den ich anzeigen möchte, nicht berücksichtigt ist vom folgenden Typ. Es ist unmöglich, es jedes Mal fest zu codieren und dann zu ändern. Daher wurde diese Methode aufgegeben.
Später habe ich mit Hilfe meiner Freunde versucht, HTML zu verwenden, um Excel
1-Methodendatei zu übertragen (weil ich muss Führe es jeden Tag regelmäßig aus, damit es nicht auf die Controller-Ebene geschrieben wird)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.结果
到这里基本就完成所有的任务了!
总结
Das obige ist der detaillierte Inhalt vonGrafisches Code-Tutorial zum Exportieren von Excel-Tabellen im YII2-Framework. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!