php+phpspreadsheet讀取Excel數據存入mysql


先生成Excel模板,然后導入Excel數據到mysql,每條數據對應圖片上傳到阿里雲

  1 <?php
  2 /**
  3  * Created by PhpStorm.
  4  * User: Administrator
  5  * Date: 2018/9/27
  6  * Time: 13:57
  7  */
  8 
  9 namespace site\admin\model;
 10 
 11 use PhpOffice\PhpSpreadsheet\Spreadsheet;
 12 use PhpOffice\PhpSpreadsheet\Writer\Xlsx;
 13 use system\library\AliYunOSS;
 14 use system\library\Unzip;
 15 
 16 class ProductBatchModel extends \site\admin\component\Model
 17 {
 18     
 19     public function add($data){
 20         
 21         if (!$this->_validate($data, 'add')) {
 22             return false;
 23         }
 24         
 25         $languageModel = new LanguageModel();
 26         $categoryModel = new CategoryModel();
 27         $productModel = new ProductModel();
 28         $urlAliasModel = new UrlAliasModel();
 29         
 30         if(substr(strrchr($data['excel_file'], '.'), 1)<>'xlsx'){
 31             $this->addError('excel_file', '請上傳xlsx格式的Excel文件');
 32             return false;
 33         }
 34         
 35         $arr_file = explode('com/', $data['excel_file']);
 36         
 37         $reader = \PhpOffice\PhpSpreadsheet\IOFactory::createReader('Xlsx');
 38         $reader->setReadDataOnly(TRUE);
 39         $spreadsheet = $reader->load(DIR_UPLOAD.$arr_file[1]); //載入excel表格
 40         
 41         $worksheet = $spreadsheet->getActiveSheet();
 42         $highestRow = $worksheet->getHighestRow(); // 總行數
 43         $highestColumn = $worksheet->getHighestColumn(); // 總列數
 44         $highestColumnIndex = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::columnIndexFromString($highestColumn); // e.g. 5
 45         
 46         $lines = $highestRow - 1;
 47         if ($lines <= 0) {
 48             $this->addError('Excel', 'Excel表格中沒有數據');
 49             return false;
 50         }
 51         
 52         $enableRow = array();
 53         $arr_url = array();
 54         
 55         for ($row = 2; $row <= $highestRow; ++$row) {
 56             
 57             /******************************驗證產品型號***********************************/
 58             
 59             $model_no = $worksheet->getCellByColumnAndRow(1, $row)->getValue();
 60             if(empty($model_no)){
 61                 $this->addError('model_no'.$row, '第'.$row.'行產品型號為空');
 62             }else{
 63                 $if_exist = $productModel->getProductByModel($model_no);
 64                 if(empty($if_exist)){
 65                     $enableRow[] = $row; //新增該行
 66                 }
 67             }
 68             
 69                 
 70             /******************************驗證產品分類***********************************/
 71             
 72             $category_name = $worksheet->getCellByColumnAndRow(2, $row)->getValue();
 73             if(empty($category_name)){
 74                 $this->addError('category_name'.$row, '第'.$row.'行分類名為空');
 75             }else{
 76                 $category = $categoryModel->getCategoryIdByName($category_name);
 77                 if(empty($category)){
 78                     $this->addError('category_name'.$row, '第'.$row.'行分類名不存在');
 79                 }
 80             }
 81             
 82                 
 83             $sort_order = $worksheet->getCellByColumnAndRow(3, $row)->getValue();
 84             if(empty($sort_order) || !is_numeric($sort_order)){
 85                 $this->addError('sort_order'.$row, '第'.$row.'行排序錯誤');
 86             }
 87             
 88             $status = $worksheet->getCellByColumnAndRow(4, $row)->getValue();
 89             if(empty($status) || !is_numeric($status)){
 90                 $this->addError('status'.$row, '第'.$row.'行狀態錯誤');
 91             }
 92                 
 93             /******************************驗證語言***********************************/
 94             
 95             $language_name = $worksheet->getCellByColumnAndRow(5, $row)->getValue();
 96             if(empty($language_name)){
 97                 $this->addError('language_name'.$row, '第'.$row.'行語言為空');
 98             }else{
 99                 $languages = $languageModel->getSysLanguageByName($language_name);
100                 if(empty($languages)){
101                     $this->addError('languages'.$row, '第'.$row.'行語言不存在');
102                 }
103             }
104             
105                 
106             $name = $worksheet->getCellByColumnAndRow(6, $row)->getValue();
107             if(empty($name)){
108                 $this->addError('name'.$row, '第'.$row.'行名稱為空');
109             }
110             
111             $keywords = $worksheet->getCellByColumnAndRow(7, $row)->getValue();
112             if(empty($keywords)){
113                 $this->addError('keywords'.$row, '第'.$row.'行關鍵詞為空');
114             }
115             
116             $url = $worksheet->getCellByColumnAndRow(10, $row)->getValue();
117             if(!empty($url)){
118                 if(in_array($url, $arr_url)){
119                     $this->addError('url'.$row, '第'.$row.'行網址重復出現');
120                 }else{
121                     $arr_url[] = $url;
122                 }
123             }
124 
125         }
126         
127         if($this->hasErrors()){
128             return false;
129         }
130 
131         //組裝數組
132         $enableData = array();
133         foreach ($enableRow as $key => $row) {
134 
135             $model_no = $worksheet->getCellByColumnAndRow(1, $row)->getValue();
136             
137             //獲取分類ID
138             $category_name = $worksheet->getCellByColumnAndRow(2, $row)->getValue();
139             $category = $categoryModel->getCategoryIdByName($category_name);
140             $category_id = $category['category_id'];
141             
142             $sort_order = $worksheet->getCellByColumnAndRow(3, $row)->getValue();
143             $status = $worksheet->getCellByColumnAndRow(4, $row)->getValue();
144             
145             //獲取語言ID
146             $language_name = $worksheet->getCellByColumnAndRow(5, $row)->getValue();
147             $languages = $languageModel->getSysLanguageByName($language_name);
148             $language_id = $languages['language_id'];
149             
150             $name = $worksheet->getCellByColumnAndRow(6, $row)->getValue();
151             $keywords = $worksheet->getCellByColumnAndRow(7, $row)->getValue();
152             $abstract = $worksheet->getCellByColumnAndRow(8, $row)->getValue();
153             $description = $worksheet->getCellByColumnAndRow(9, $row)->getValue();
154             $url = $worksheet->getCellByColumnAndRow(10, $row)->getValue();
155             $meta_title = $worksheet->getCellByColumnAndRow(11, $row)->getValue();
156             $meta_keyword = $worksheet->getCellByColumnAndRow(12, $row)->getValue();
157             $meta_description = $worksheet->getCellByColumnAndRow(13, $row)->getValue();
158             
159             if(!isset($enableData[$model_no])){
160                 $enableData[$model_no] = array(
161                         'product_type_id'=>'',
162                         'model_no'=>$model_no,
163                         'sort_order'=>$sort_order,
164                         'status'=>$status,
165                         'category'=>array($category_id),
166                         'trade'=>'',
167                         'producttradeinfo'=>array()
168                 );
169             }
170             
171             $enableData[$model_no]['desc'][$language_id] = array(
172                     'description'=>$description,
173                     'name'=>$name,
174                     'abstract'=>$abstract,
175                     'keywords'=>$keywords,
176                     'language_name'=>$language_name,
177                     'meta_title'=>$meta_title,
178                     'meta_keyword'=>$meta_keyword,
179                     'meta_description'=>$meta_description,
180                     'url_alias'=>$url
181             );
182             
183         }
184         
185         //遍歷檢測網址
186         foreach ($enableData as $key => $value){
187             if(isset($value['desc']) && !empty($value['desc'])){
188                 foreach ($value['desc'] as $k => $v){
189                     $cc = $urlAliasModel->validate(['keyword' => $v['url_alias'], 'language_id' => $k, 'query' => ''],'add');
190                     if($cc==false){
191                         return false;
192                     }
193                 }
194             }
195         }
196 
197         //解壓縮圖片壓縮包
198         $dirPath = DIR_UPLOAD.$this->session->data['site_id'];
199         $file = $dirPath.'/'.$data['images_file'];
200         if(!file_exists($file) || (substr(strrchr($file, '.'), 1)<>'zip')){
201             $this->addError('imageZip', '請上傳產品圖片壓縮包(zip格式)');
202             return false;
203         }
204         $z    = new Unzip;
205         $info = $z->unzip($file, $dirPath.'/', true, false);
206         if($info){
207             unlink($file); //刪除壓縮包
208         }
209 
210         //獲取產品圖片
211         foreach ($enableData as $key => $value){            
212             $enableData[$key]['image'] = $this->_getImage($key,$dirPath.'/'.basename($data['images_file'],'.zip'));
213         }
214 
215         foreach ($enableData as $key => $value){
216             try {
217                 $productModel->add($value);
218             } catch (Exception $e) {
219                 $this->addError('add', $e->getMessage());
220                 return false;
221             }
222         }
223         return true;
224 
225     }
226     
227     /**
228      * 生成模板
229      *
230      * @access public
231      * @return void
232      */
233     public function createTemplate()
234     {
235         
236         $languageModel = new LanguageModel();
237         $languages = $languageModel->getEnabledLanguages();
238         
239         $categoryModel = new CategoryModel();
240         $category = $categoryModel->getRecursionCategory();
241         $categoryNme = $this->_getCategoryName($category);
242         
243         $columnNum = 3000;
244         
245         $spreadsheet = new Spreadsheet();
246         
247         /*****************************************設置當前活動頁內容***********************************/
248         
249         $sheet = $spreadsheet->getActiveSheet();
250         $sheet->setCellValue('A1', '型號(必填)');
251         $sheet->setCellValue('B1', '分類名(必填)');
252         $sheet->setCellValue('C1', '排序(必填,請輸入數字)');
253         $sheet->setCellValue('D1', '狀態(必填,1=上架|0=下架)');        
254         $sheet->setCellValue('E1', '語言(必填)');
255         $sheet->setCellValue('F1', '名稱(必填)');
256         $sheet->setCellValue('G1', '關鍵詞(必填)');
257         $sheet->setCellValue('H1', '簡要描述');
258         $sheet->setCellValue('I1', '詳細描述');
259         $sheet->setCellValue('J1', '網址');
260         $sheet->setCellValue('K1', 'seo標題');
261         $sheet->setCellValue('L1', 'seo關鍵詞');
262         $sheet->setCellValue('M1', 'seo描述');
263         
264         //設置相關屬性
265         $sheet->setTitle('Product');
266         $sheet->getDefaultColumnDimension()->setWidth(30);
267         $sheet->getStyle('A1:M1')->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID);
268         $sheet->getStyle('A1:M1')->getFill()->getStartColor()->setARGB('FF808080');
269         $sheet->getStyle('A1:M1')->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
270         
271         //分類列
272         for($i=2;$i<=$columnNum;$i++){
273             $objValidation = $sheet->getDataValidation('B'.$i);
274             $objValidation -> setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST)
275             -> setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION)
276             -> setAllowBlank(false)
277             -> setShowInputMessage(true)
278             -> setShowErrorMessage(true)
279             -> setShowDropDown(true)
280             -> setErrorTitle('輸入的值有誤')
281             -> setError('您輸入的值不在下拉框列表內')
282             -> setPrompt('請選擇下拉框列表中的值')
283             -> setFormula1('data!$C$3:$C$'.(count($categoryNme)+2));
284         }
285         
286         //狀態列
287         for($i=2;$i<=$columnNum;$i++){
288             $objValidation = $sheet->getDataValidation('D'.$i);
289             $objValidation -> setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST)
290             -> setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION)
291             -> setAllowBlank(false)
292             -> setShowInputMessage(true)
293             -> setShowErrorMessage(true)
294             -> setShowDropDown(true)
295             -> setErrorTitle('輸入的值有誤')
296             -> setError('您輸入的值不在下拉框列表內')
297             -> setPrompt('請選擇下拉框列表中的值')
298             -> setFormula1('data!$A$3:$A$4');
299         }
300         
301         //語言列
302         for($i=2;$i<=$columnNum;$i++){
303             $objValidation = $sheet->getDataValidation('E'.$i);
304             $objValidation -> setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST)
305             -> setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_INFORMATION)
306             -> setAllowBlank(false)
307             -> setShowInputMessage(true)
308             -> setShowErrorMessage(true)
309             -> setShowDropDown(true)
310             -> setErrorTitle('輸入的值有誤')
311             -> setError('您輸入的值不在下拉框列表內')
312             -> setPrompt('請選擇下拉框列表中的值')
313             -> setFormula1('data!$B$3:$B$'.(count($languages)+2));
314         }
315         
316         
317         
318         /*******************************************新增一個活動頁,放公共數據*********************************/
319         
320         $spreadsheet->createSheet();
321         $spreadsheet->setActiveSheetIndex(1);
322         $sheet = $spreadsheet->getActiveSheet();
323         $sheet->setTitle('data');
324         $sheet->getDefaultColumnDimension()->setWidth(25);
325         $sheet->mergeCells('A1:C1');
326         $styleArray = [
327                 'alignment' => [
328                         'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER,
329                         'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER,
330                 ],
331         ];
332         $sheet->getStyle('A1')->applyFromArray($styleArray);
333         $sheet->getRowDimension('1')->setRowHeight(35);
334         
335         $sheet->getStyle('A1')->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID);
336         $sheet->getStyle('A1')->getFill()->getStartColor()->setARGB('8B0000');
337         $sheet->getStyle('A1')->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
338         $sheet->setCellValue('A1', '公共數據(請不要修改)');
339         
340         $sheet->getStyle('A2:C2')->getFill()->setFillType(\PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID);
341         $sheet->getStyle('A2:C2')->getFill()->getStartColor()->setARGB('FF808080');
342         $sheet->getStyle('A2:C2')->getFont()->getColor()->setARGB(\PhpOffice\PhpSpreadsheet\Style\Color::COLOR_WHITE);
343         
344         $sheet->setCellValue('A2', '狀態(1=上架|0=下架)');
345         $sheet->setCellValue('A3', '0');    
346         $sheet->setCellValue('A4', '1');
347         
348         $sheet->setCellValue('B2', '語言');
349         foreach ($languages as $key => $value){
350             $sheet->setCellValue('B'.($key+3), $value['name']);
351         }
352         
353         $sheet->setCellValue('C2', '分類名');
354         foreach ($categoryNme as $key => $value){
355             $sheet->setCellValue('C'.($key+3), $value);
356         }
357         
358         $sheet->setSheetState('hidden');
359         
360         //設置第一頁為活動頁,保存
361         $spreadsheet->setActiveSheetIndex(0);
362         $writer = new Xlsx($spreadsheet);
363         $file_name = $this->session->data['site_id'].'.xlsx';
364         $file_path = DIR_UPLOAD.'excel_template/'.$file_name;
365         $writer->save($file_path);
366         
367         //釋放內存
368         $spreadsheet->disconnectWorksheets();
369         unset($spreadsheet);
370     
371         return $file_name;
372     }
373     
374     /**
375      * 驗證
376      * @access private
377      * @param array $data
378      * @param string $scenario 驗證場景 add
379      * @return bool
380      */
381     private function _validate($data, $scenario = '')
382     {
383     
384         if (!isset($data['excel_file']) || empty($data['excel_file'])) {
385             $this->addError('excel_file', '沒有上傳產品Excel文件');
386         }
387         
388         if (!isset($data['images_file']) || empty($data['images_file'])) {
389             $this->addError('images_file', '沒有上傳產品圖片文件');
390         }
391     
392         return $this->hasErrors() ? false : true;
393     }
394     
395     /**
396      * 獲取產品分類名稱
397      * @access private
398      * @param array $data
399      * @return array
400      */
401     private function _getCategoryName($data){
402         
403         if(!empty($data)){
404             
405             foreach ($data as $key => $value){
406                 if(!empty($data['children'])){
407                     $this->_getCategoryName($data['children']);
408                 }else{
409                     $retrun[] = $value['name'];
410                 }
411             }
412             
413         }else{
414             $retrun = array();
415         }
416         
417         return $retrun;
418         
419     }
420     
421     /**
422      * 遍歷文件夾
423      * @access private
424      * @param string $dir
425      * @return array
426      */
427     private function _getDirFile($dir) {
428         $files = array();
429         if(@$handle = opendir($dir)) { //注意這里要加一個@,不然會有warning錯誤提示:)
430             while(($file = readdir($handle)) !== false) {
431                 if($file != ".." && $file != ".") { //排除根目錄;
432                     if(is_dir($dir."/".$file)) { //如果是子文件夾,就進行遞歸
433                         $files[$file] = $this->_getDirFile($dir."/".$file);
434                     } else { //不然就將文件的名字存入數組;
435                         $files[] = $file;
436                     }
437     
438                 }
439             }
440             closedir($handle);
441             return $files;
442         }
443     }
444     
445     /**
446      * 獲取產品圖片
447      * @access private
448      * @param string $dir
449      * @return array
450      */
451     private function _getImage($key,$images_file){
452 
453         $aliYunOSS = new AliYunOSS();
454         $data = array();
455         $arr_image = $this->_getDirFile($images_file);
456         
457         if(isset($arr_image[$key])){
458 
459             foreach ($arr_image[$key] as $k => $v){
460                 $result = $aliYunOSS->uploadFile($images_file.'/'.$key.'/'.$v, 'upload/images/'.$key.'/'.$v);
461                 if($result['success']==1){
462                     $data[] = array(
463                             'name'=>$v,
464                             'image'=>$result['info']['url']
465                     );
466                 }
467             }
468             
469         }
470         
471         return $data;
472     }
473 
474 }

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM