excel export / import
yoyocmf 2019-01-25 15:47:33

v2.0 Excel导入

 

2021-05-18优化

1、在view层加一个入口,打开upload的页面

PHP Code复制内容到剪贴板
  1. <?= Html::createLayer(["upload"],'excel批量导入', ['class' => 'btn btn-danger btn-outline','data-title'=>'excel批量导入']) ?>  

 

也可以指定标题和窗口大小:

PHP Code复制内容到剪贴板
  1. <?= Html::createLayer(["import-member""org_id" => $org_id], "<span>excel批量导入</span>", [  
  2.     "class" => "dropdown-item modify-selected-item",  
  3.     "data-title" => "批量导入成员",  
  4.     "data-height" => "570px"  
  5. ]) ?>  

 

 

2、在controller层加控制器:

PHP Code复制内容到剪贴板
  1. public function actionUpload(){  
  2.     if (Yii::$app->request->isPost){  
  3.         $projectId = Yii::$app->request->post("project_id");  
  4.         $path = date("Ymd")."/"//后缀一定要加/  
  5.         $file = UploadedFile::getInstancesByName("file");  
  6.         if(!$file){  
  7.             Yii::$app->session->setFlash("error","未获取到提交的文件,请检查");  
  8.             return $this->render('upload');  
  9.         }  
  10.         $res = InvestmentContract::import($path,$file[0],"local",$projectId);  
  11.         if(!$res){  
  12.             Yii::$app->session->setFlash("success""导入成功");  
  13.         }else{  
  14.             Yii::$app->session->setFlash("error"$res);  
  15.         }  
  16.     }  
  17.     return $this->render('upload');  
  18. }  

 

在model层添加:

use common\helpers\ExcelHelper;

use common\modules\attachment\components\UploadedFile;

use common\modules\attachment\models\Attachment;

PHP Code复制内容到剪贴板
  1.     /** 
  2.      * excel导入 
  3.      * @param $uploadBaseLocalPath *文件上传后存储在本地的前缀 
  4.      * @param UploadedFile $uploadedFile *文件二进制流 
  5.      * @param string $drive *存储引擎,oss / local 
  6.      * @param int $projectId 
  7.      * @return bool|mixed 
  8.      * @throws \PhpOffice\PhpSpreadsheet\Exception 
  9.      * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception 
  10.      */  
  11.     public static function import($uploadBaseLocalPath, UploadedFile $uploadedFile$drive = "local"$projectId = 0)  
  12.     {  
  13.         // 先上传  
  14.         $uploadFile = Attachment::uploadFromPost($uploadBaseLocalPath$uploadedFile$drive);  
  15.         if ($uploadFile->extension == "xlsx") {  
  16.             $excelData = ExcelHelper::importOnlyXlsx(Yii::$app->storage->getFullPath($uploadFile->path), 2);  
  17.         } else {  
  18.             $excelData = ExcelHelper::import(Yii::$app->storage->getFullPath($uploadFile->path), 2);  
  19.         }  
  20.         // Excel的数据过滤  
  21.         $model = new self();  
  22.         foreach ($excelData as $k => $v) {  
  23.             if ($v[0] && $v[1]) {  
  24.                 // 必须编号和名称都存在,否则不予处理  
  25.   
  26.                 // 当前是否存在  
  27.                 $ifExist = self::find()->where(["code" => $v[0], "title" => $v[1], "project_id" => $projectId])->one();  
  28.                 if (!$ifExist) {  
  29.                     // 如果不存在,重新写入  
  30.                     // p2($v);  
  31.                     // 使用AR写入  
  32.                     $_model = clone $model;  
  33.                     $_model->code = strval($v[0]);// 转string  
  34.                     $_model->title = $v[1];  
  35.                     $_model->second_part = $v[2];  
  36.                     $_model->contract_amount = $v[3];//DebrisHelper::floatNumber(  
  37.                     $_model->temp_amount = $v[4];//DebrisHelper::floatNumber(  
  38.                     $_model->no_cost_amount = $v[5]; //不需要转换成万元  
  39.                     $_model->sign_amount_hs = $v[6];  
  40.                     $_model->sign_amount_bhs = $v[7]; //不需要转换成万元  
  41.                     $_model->sign_time = $v[8];  
  42.                     $_model->project_id = $projectId;  
  43. //                    p($_model);  
  44.                     if (!$_model->save()) {  
  45.                         return current($_model->firstErrors);  
  46.                     };  
  47.                     // 使用原生写入  
  48. //                Yii::$app->db->createCommand()->insert(self::tableName(), [  
  49. //                    'name' => $name,  
  50. //                    'project_id' => $projectId,  
  51. //                    'parent_id' => $bclassid  
  52. //                ])->execute();  
  53.                 }  
  54.   
  55.             }  
  56.         }  
  57.         return false;  
  58.   
  59.     }  

 

如果有父级编号:

PHP Code复制内容到剪贴板
  1. /** 
  2.  * excel导入 
  3.  * @param $uploadBaseLocalPath *文件上传后存储在本地的前缀 
  4.  * @param UploadedFile $uploadedFile *文件二进制流 
  5.  * @param string $drive *存储引擎,oss / local 
  6.  * @param int $projectId 
  7.  * @return bool|mixed 
  8.  * @throws \PhpOffice\PhpSpreadsheet\Exception 
  9.  * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception 
  10.  */  
  11. public static function import($uploadBaseLocalPath, UploadedFile $uploadedFile$drive = "local"$projectId = 0)  
  12. {  
  13.     // 先上传  
  14.     $uploadFile = Attachment::uploadFromPost($uploadBaseLocalPath$uploadedFile$drive);  
  15.     if ($uploadFile->extension == "xlsx") {  
  16.         $excelData = ExcelHelper::importOnlyXlsx(Yii::$app->storage->getFullPath($uploadFile->path), 2);  
  17.     } else {  
  18.         $excelData = ExcelHelper::import(Yii::$app->storage->getFullPath($uploadFile->path), 2);  
  19.     }  
  20.     // Excel的数据过滤  
  21.     $model = new self();  
  22.     foreach ($excelData as $k => $v) {  
  23.         if ($v[0] && $v[2]) {  
  24.             // 必须编号和名称都存在,否则不予处理  
  25.             // 当前是否存在  
  26.             $ifExist = self::find()->where(["code" => $v[0]])->one();  
  27.             if ($v[1]) {  
  28.                 // 如果有父编号  
  29.                 $parentId = self::find()->select("class_id")->where(["code" => $v[1]])->scalar();  
  30.             } else {  
  31.                 $parentId = 0;  
  32.             }  
  33.             if (!$ifExist) {  
  34.                 // 如果不存在,重新写入  
  35.                 // 使用AR写入  
  36.                 $_model = clone $model;  
  37.             } else {  
  38.                 // 如果存在就更新  
  39.                 $_model = $ifExist;  
  40.             }  
  41.             $_model->code = strval($v[0]);// 转string  
  42.             $_model->parent_class_id = intval($parentId);// 转string  
  43.             $_model->title = $v[2];
  44.             $_model->project_id = $projectId;  
  45.             if (!$_model->save()) {  
  46.                 return current($_model->firstErrors);  
  47.             };  
  48.         }  
  49.     }  
  50.     return false;  
  51. }  

 

 

3、upload的view:

XML/HTML Code复制内容到剪贴板
  1. <?php  
  2. use common\helpers\Html;  
  3. use backend\widgets\ActiveForm;  
  4. ?>  
  5.   
  6. <div class="page material-create">  
  7.     <div class="page-content">  
  8.         <?php $form = ActiveForm::begin([  
  9.             'options' => [  
  10.                 "enctype" => "multipart/form-data",  
  11.             ],  
  12.         ]); ?>  
  13.         <div class="panel">  
  14.             <div class="panel-body">  
  15.                 <div class="form-group form-material">  
  16.                     <label class="col-form-label" for="select">选择项目</label>  
  17.                     <?= Html::dropDownList("project_id", null, \common\modules\project\models\Project::getDropDownList(), ['encode' => false, 'class' => 'form-control','prompt' => '不限项目']) ?>  
  18.                 </div>  
  19.   
  20.                 <div class="form-group form-material">  
  21.                     <label class="col-form-label" for="inputFile">文件域</label>  
  22.                     <input type="text" class="form-control" placeholder="请选择文件.." readonly="">  
  23.                     <input type="file" id="inputFile" name="file">  
  24.                 </div>  
  25.             </div>  
  26.             <div class="panel-footer">  
  27.                 <button class="btn btn-primary">开始导入</button>  
  28.             </div>  
  29.         </div>  
  30.         <?php ActiveForm::end(); ?>  
  31.   
  32.     </div>  
  33. </div>  

 

 

v2.0 excel 导出

 

view层添加:

PHP Code复制内容到剪贴板
  1. <?= Html::a('excel导出',["export"], ['class' => 'btn btn-success btn-outline mr-5','data-title'=>'excel批量导出']) ?>  

 

controller控制器添加:

PHP Code复制内容到剪贴板
  1. /** 
  2.  * Excel导出 
  3.  * @return bool 
  4.  * @throws \PhpOffice\PhpSpreadsheet\Exception 
  5.  * @throws \PhpOffice\PhpSpreadsheet\Writer\Exception 
  6.  */  
  7. public function actionExport()  
  8. {  
  9.     $list = ProjectProphaseScheduleCommon::find()->with("parent")->all();  
  10.     $header = [  
  11.         ['编号''code''text''attribute' => ['width' => 8]],  
  12.         ['父编号''parent_id''function'function ($model) {  
  13.             return $model["parent_id"] ? $model->parent->code : $model["parent_id"];  
  14.         }, 'attribute' => ['width' => 8]],  
  15.         ['副标题''sub_title''text''attribute' => ['width' => 10]],  
  16.         ['标题''title''text''attribute' => ['width' => 80,'wrap' => true]],  
  17.         ['说明''description''text''attribute' => ['width' => 10]],  
  18.         ['前端边框样式''type''text''attribute' => ['width' => 10]],  
  19.         ['是否展示子级''is_show_children''text''attribute' => ['width' => 10]],  
  20.     ];  
  21.     ExcelHelper::exportData($list$header,"拆迁前期公共配置项导出");  
  22.     return $this->goBack();  
  23. }  

 

 

PHP Code复制内容到剪贴板
  1. // [名称, 字段名, 类型, 类型规则]  
  2. $header = [  
  3.     ['ID''id''text'],  
  4.     ['手机号码''mobile'], // 规则不填默认text  
  5.     ['openid''fans.openid''text'],  
  6.     ['昵称''fans.nickname''text'],  
  7.     ['关注/扫描''type''selectd', [1 => '关注', 2 => '扫描']],  
  8.     ['性别''sex''function'function($model){  
  9.         return $model['sex'] == 1 ? '男' : '女';  
  10.     }],  
  11.     ['创建时间''created_at''date''Y-m-d'],  
  12. ];  
  13.   
  14. $list = [  
  15.     [  
  16.         'id' => 1,  
  17.         'type' => 1,  
  18.         'fans' => [  
  19.             'openid' => '123',  
  20.             'nickname' => '昵称',  
  21.         ],  
  22.         'sex' => 1,  
  23.         'create_at' => time(),  
  24.     ]  
  25. ];  

  

PHP Code复制内容到剪贴板
  1. // attribute传参表格列宽度 ,width 设置列宽度,wrap是否自动换行   
  2.     
  3.         $list = ProjectProphaseScheduleCommon::find()->with("parent")->all();    
  4.         $header = [    
  5.             ['编号''code''text''attribute' => ['width' => 20]],    
  6.             ['父编号''parent_id''function'function ($model) {    
  7.                 return $model["parent_id"] ? $model->parent->code : $model["parent_id"];    
  8.             }],    
  9.             ['副标题''sub_title''text'],    
  10.             ['标题''title''text'],    
  11.             ['说明''description''text'],    
  12.             ['前端边框样式''type''text'],    
  13.             ['是否展示子级''is_show_children''text'],    
  14.         ];    
  15.         ExcelHelper::exportData($list$header);    

 

 

PHP Code复制内容到剪贴板
  1. // 简单使用  
  2. return ExcelHelper::exportData($list$header);  
  3.   
  4. // 定制 默认导出xlsx 支持 : xlsx/xls/html/csv  
  5. return ExcelHelper::exportData($list$header'测试''xlsx');  

 

 


 

1、在view层加一个入口,打开upload的页面

PHP Code复制内容到剪贴板
  1. <?= Html::createLayer(["upload"],'excel批量导入', ['class' => 'btn btn-danger btn-outline','data-title'=>'excel批量导入']) ?>  

 

2、在controller层加控制器:

PHP Code复制内容到剪贴板
  1. public function actionUpload(){  
  2.     if (Yii::$app->request->isPost){  
  3.         $projectId = Yii::$app->request->post("project_id");  
  4.         $path = date("Ymd")."/"//后缀一定要加/  
  5.         $file = UploadedFile::getInstancesByName("file");  
  6.         if(!$file){  
  7.             Yii::$app->session->setFlash("error","未获取到提交的文件,请检查");  
  8.             return $this->render('upload');  
  9.         }  
  10.         $uploadFile = Attachment::uploadFromPost($path,$file[0],"local");  
  11.         if($uploadFile->extension == "xlsx"){  
  12.             $excelData = ExcelHelper::importOnlyXlsx( Yii::$app->storage->getFullPath($uploadFile->path),2);  
  13.         }else{  
  14.             $excelData = ExcelHelper::import( Yii::$app->storage->getFullPath($uploadFile->path),2);  
  15.         }  
  16.   
  17.         // Excel的数据过滤  
  18.         $data = [];  
  19.         foreach ($excelData as $k => $v){  
  20.             if($v[0]){  
  21.                 // 过滤名称为空的物资  
  22.                 $data[] = $v;  
  23.             }  
  24.         }  
  25.         $excelData = $data;  
  26.         // Excel数据过滤完成  
  27.   
  28.         if($excelData && is_array($excelData)){  
  29.   
  30.             foreach ($excelData as $k =>&$v){  
  31.                 $v[] = $projectId;  
  32.             }  
  33.             Yii::$app->db->createCommand()->batchInsert(Material::tableName(), ['title''branch','subentry','category','specification','unit','cmt_total','cmt_cur_total','cmt_alm','project_id'], $excelData)->execute();  
  34.             Yii::$app->session->setFlash("success","导入成功");  
  35.         }else{  
  36.             Yii::$app->session->setFlash("error","读取失败,请检查文件");  
  37.         }  
  38.     }  
  39.     return $this->render('upload');  
  40. }  

 

3、upload的view:

use common\helpers\ExcelHelper;
use common\modules\attachment\components\UploadedFile;
use common\modules\attachment\models\Attachment;

PHP Code复制内容到剪贴板
  1. <?php  
  2. use common\helpers\Html;  
  3. use backend\widgets\ActiveForm;  
  4. ?>  
  5.   
  6. <div class="page material-create">  
  7.     <div class="page-content">  
  8.         <?php $form = ActiveForm::begin([  
  9.             'options' => [  
  10.                 "enctype" => "multipart/form-data",  
  11.             ],  
  12.         ]); ?>  
  13.         <div class="panel">  
  14.             <div class="panel-body">  
  15.                 <div class="form-group form-material">  
  16.                     <label class="col-form-label" for="select">选择项目</label>  
  17.                     <?= Html::dropDownList("project_id", null, \common\modules\project\models\Project::getDropDownList(), ['encode' => false, 'class' => 'form-control']) ?>  
  18.                 </div>  
  19.   
  20.                 <div class="form-group form-material">  
  21.                     <label class="col-form-label" for="inputFile">文件域</label>  
  22.                     <input type="text" class="form-control" placeholder="请选择文件.." readonly="">  
  23.                     <input type="file" id="inputFile" name="file">  
  24.                 </div>  
  25.             </div>  
  26.             <div class="panel-footer">  
  27.                 <button class="btn btn-primary">开始导入</button>  
  28.             </div>  
  29.         </div>  
  30.         <?php ActiveForm::end(); ?>  
  31.   
  32.     </div>  
  33. </div>  

 

 

 


 

 

1、报错:The 'gridview' module MUST be setup in your Yii configuration file.

config中添加module:

PHP Code复制内容到剪贴板
  1. 'modules' => [  
  2.     'gridview' => [  
  3.         'class' => 'kartik\grid\Module'  
  4.     ],  
  5.     ...  
  6. ]  

 

示例:excel导出

use backend\widgets\export\ExportMenu;

 

尽量不使用导出为excel2007的,宽度不生效,所以在ExportMenu中作了判断处理,如果强制加setWidth,在excel2007中会出现未写入,空白表格,有熟悉的小伙伴有解决方案可直接留言,谢谢

PHP Code复制内容到剪贴板
  1.  
  2.                 $gridColumns = [    
  3. //                    ['class' => 'kartik\grid\SerialColumn'],    
  4.                     [    
  5.                         'attribute' => 'parent_id',    
  6.                         'label' => '上级部门',    
  7.                         'vAlign' => 'middle',    
  8.                         'width' => '18',    
  9.                         'value' => function ($model$key$index$widget) {    
  10.                             return $model->parentName;    
  11.                         },    
  12.                         'format' => 'raw'    
  13.                     ],    
  14.                     [    
  15.                         'attribute' => 'department_name',    
  16.                         'vAlign' => 'middle',    
  17.                         'width' => '18',    
  18.                         'format' => 'raw'    
  19.                     ],    
  20.                     'level',    
  21.                 ];    
  22.     
  23.                 echo ExportMenu::widget([    
  24.                     'dataProvider' => $dataProvider,    
  25.                     'columns' => $gridColumns,    
  26.                     'filename' => '部门列表',    
  27.                     'autoWidth' => false, //如果上面传了width,这里的自适应宽度,必须为false    
  28.                     'exportConfig' => [    
  29. //                        ExportMenu::FORMAT_HTML => false,  
  30. //                        ExportMenu::FORMAT_CSV => false,  
  31. //                        ExportMenu::FORMAT_PDF => false,  
  32. //                        ExportMenu::FORMAT_TEXT => false,  
  33. //                        ExportMenu::FORMAT_EXCEL_X => false,  
  34.                         ExportMenu::FORMAT_PDF => [    
  35.                             'pdfConfig' => [    
  36.                                 'options' => [    
  37.                                     'ignore_invalid_utf8' => true,    
  38.                                     'tabSpaces' => 4,    
  39.                                     'autoLangToFont' => true,    //这几个配置加上可以显示中文    
  40.                                     'autoScriptToLang' => true,  //这几个配置加上可以显示中文    
  41.                                     'autoVietnamese' => true,    //这几个配置加上可以显示中文    
  42.                                     'autoArabic' => true,        //这几个配置加上可以显示中文    
  43.                                 ]    
  44.                             ],    
  45.                         ],    
  46.                     ],    
  47. //                    'showConfirmAlert' => false //是否弹出确认框    
  48.                 ]);    

 

 

示例:excel导入(参考 用户管理 - 部门管理)

controller加入:

PHP Code复制内容到剪贴板
  1.     public function actions()  
  2.     {  
  3.         return [  
  4.             'import' => [  
  5.                 'class' => 'backend\\actions\\AjaxImportAction',  
  6.                 'entity' => Department::className(),  
  7. //                'function' => 'import', //默认为import,选填,导入的方法,多个可添加不同的方法  
  8.             ],  
  9.         ];  
  10.     }  

 

model中添加import方法:

PHP Code复制内容到剪贴板
  1. /** 
  2.  * 导入 
  3.  * @param $uploadfile       * 上传的文件完整物理路径 
  4.  * @param $post             * 导入的post表单中传递的参数,如类型://1是质量问题,2是安全问题 
  5.  * @return bool 
  6.  * @throws \PhpOffice\PhpSpreadsheet\Exception 
  7.  * @throws \PhpOffice\PhpSpreadsheet\Reader\Exception 
  8.  */  
  9. function import($uploadfile,$post){  
  10.     $type = $post['type'];  
  11.     $tool = new \common\components\Tool();  
  12.     $excel = $tool->readExcel($uploadfile,2); //读取excel内容,从第二行开始,第一行是标题  
  13.     if($excel["errcode"] != 0){  
  14.         return $excel["errmsg"];  
  15.     }  
  16.     $data = $excel["data"];  
  17.   
  18.     $model = new self();  
  19.     $projectId = Yii::$app->session->get("project_id");  
  20.     foreach ($data as $k => $v){  
  21.         $parentName = $v[1]; //父级名称  
  22.         $name = $v[2];       //部门名称  
  23.         $level = $v[3];      //部门级别  
  24.   
  25.         if(!$name){  
  26.             // 如果没有部门名称,跳出循环  
  27.             continue;  
  28.         }  
  29.   
  30.         $m = clone $model;  
  31.   
  32.         // 重要,加条件project_id  
  33.         $r = $model->find()->where(["department_name"=>$name,"project_id"=>$projectId])->one();  
  34.         if($r){  
  35.             $m = $r;  
  36.         }  
  37.   
  38.         // 重要,加条件project_id  
  39.         $parentId = $m->find()->select('department_id')->where(['department_name' => $parentName,"project_id"=>$projectId])->scalar();  
  40.         if($parentId){  
  41.             $m->parent = $parentId;  
  42.         }else{  
  43.             $newM = clone $model;  
  44.             $newM->department_name = $parentName;  
  45.             $newM->project_id = $projectId;  
  46.             $newM->save();  
  47.             $m->parent = $newM->department_id;  
  48.         }  
  49.         $m->project_id = $projectId;  
  50.         $m->department_name = $name;  
  51.         $m->level = $level;  
  52.         $m->save();  
  53.     };  
  54.     return false;  
  55. }  

 


 

1.png

PHP Code复制内容到剪贴板
  1.         echo ExportMenu::widget([  
  2.             'dataProvider' => $dataProvider,  
  3.             'columns' => $gridColumns,  
  4.             'filename' => '库存列表',  
  5.             'clearBuffers' => true,  
  6.             'autoWidth' => false,  
  7.             'dropdownOptions' => [  
  8.                 'label' => '选择导出格式',  
  9.                 'class' => 'btn btn-secondary'  
  10.             ],  
  11.             'columnSelectorOptions'=>[  
  12.                 'label' => '选择导出字段',  
  13. //                'icon' => '<i class="glyphicon glyphicon-heart"></i>',  
  14. //                'title' => '鼠标放上去显示的文字'  
  15.             ],  
  16.             'exportConfig' => [  
  17. //                        ExportMenu::FORMAT_HTML => false,  
  18.                 ExportMenu::FORMAT_CSV => false,  
  19. //                        ExportMenu::FORMAT_PDF => false,  
  20. //                        ExportMenu::FORMAT_TEXT => false,  
  21.                 ExportMenu::FORMAT_EXCEL_X => false,  
  22.                 ExportMenu::FORMAT_PDF => [  
  23.                     'pdfConfig' => [  
  24.                         'options' => [  
  25.                             'ignore_invalid_utf8' => true,  
  26.                             'tabSpaces' => 4,  
  27.                             'autoLangToFont' => true,    //这几个配置加上可以显示中文  
  28.                             'autoScriptToLang' => true,  //这几个配置加上可以显示中文  
  29.                             'autoVietnamese' => true,    //这几个配置加上可以显示中文  
  30.                             'autoArabic' => true,        //这几个配置加上可以显示中文  
  31.                         ]  
  32.                     ],  
  33.                 ],  
  34.             ],  
  35.         ]);  

 

 

本文来自于:http://www.yoyo88.cn/note/yoyocmf/406.html

Powered by yoyo苏ICP备15045725号