正常的excel匯出沒什麼問題,最近一直頭疼的是怎麼匯出資料中包含圖片,並且圖片還是陣列?????by user 悅悅 https://www.cnblogs.com/nuanai
1、匯出的excel佈局是圖片分行顯示
2、匯出圖片路徑,並且已另外的文字設定超連結
3、其他行合併(這個還沒有想好怎麼設定合併後賦值)
使用的框架是fastadmin,就要引入必要的PhpOffice包,不必介紹,其中使用到了匯出excel的檔案、超連結檔案、單元格樣式檔案 by user 悅悅 https://www.cnblogs.com/nuanai
1 use PhpOffice\PhpSpreadsheet\Spreadsheet; 2 use PhpOffice\PhpSpreadsheet\Writer\Xlsx; 3 use PhpOffice\PhpSpreadsheet\Writer\Xls; 4 5 use PhpOffice\PhpSpreadsheet\Cell\Hyperlink; 6 use PhpOffice\PhpSpreadsheet\Style\Alignment;
使用sql語句將資料庫需要匯出的資料進行查詢成結果集,正常的查詢語句不做過多介紹(控制器命名不做過多介紹,懂得都懂哈)
這裡使用的連表查詢,查詢出需要匯出的欄位;有時間欄位的,如果資料庫中存的是時間戳,需要進行格式化後賦值 by user 悅悅 https://www.cnblogs.com/nuanai
1 $dataList = Db::name('inspection_project_site') 2 ->alias('site') 3 ->field('staff.staff_name,asite.code,asite.code,site_name,site.latlng,site.check_lnglat,site.checktime,site.images') 4 ->join('inspection_staff staff','staff.id = site.staff_id','LEFT') 5 ->join('inspection_area_site asite','asite.id = site.area_site_id','LEFT') 6 ->where('status',1) 7 ->order(['site.checktime'=>'desc']) 8 ->select(); 9 10 foreach ($dataList as $k => &$v) 11 { 12 $v['checktime'] = isset($v['checktime']) ? date('Y-m-d H:i:s',$v['checktime']) : ""; 13 }
需要匯出的欄位已經有了,那麼下面就是進行excel的工程,想要匯出excel就要使用到上面引入的PHPoffice包
設定匯出excel表的檔名稱、表頭名稱和單元格大小等樣式,可以使用資料庫欄位,也可以自己先設定好,我這邊是提前設定好的 by user 悅悅 https://www.cnblogs.com/nuanai
1 $filename = '巡檢記錄'; 2 $spreadsheet = new Spreadsheet(); 3 $worksheet = $spreadsheet->getActiveSheet(); 4 5 $title = ['巡檢員','巡檢點編號','巡檢點名稱','巡檢經緯度','打卡經緯度','打卡時間','打卡圖片']; 6 $cell_width = [15,10,25,20,20,20,25,30,10,10,30,10,20,10,10,10,10,20,20,20,20,20,20,20,15,15,10]; 7 8 $titCol = 'A';// 表頭單元格內容 第一行 9 10 foreach ($title as $k=>$value) { 11 // 單元格內容寫入 12 $worksheet->setCellValue($titCol . '1', $value); 13 if (isset($cell_width[$k])){ 14 $worksheet->getColumnDimension($titCol)->setWidth($cell_width[$k]); 15 } 16 $titCol++; 17 } 18 19 $styleArray = [ 20 'font' => [ 21 'bold' => true 22 ], 23 'alignment' => [ 24 'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 25 ], 26 ]; 27 //設定單元格樣式 28 $worksheet->getStyle('A1:V1')->applyFromArray($styleArray)->getFont()->setSize(12);
配置好基本要素後,就是資料內容的寫入了,這邊圖片的欄位是用“逗號”進行拼接的字串,所以當寫入excel中時,需要判斷圖片欄位進行逗號拆分為陣列,然後分條寫入excel表中 by user 悅悅 https://www.cnblogs.com/nuanai
讓我比較頭疼的是,之前的迴圈寫入有點錯誤,大家一定要注意,迴圈的順序。錯誤是圖片寫入後,又被下一條的資料給覆蓋了,所以一定要計算好圖片需要用到多少行,並且下一條寫入時要圖片的行數+1才不會覆蓋上一條的圖片
1 $maxImageCount = !empty($dataRow['images']) ? count(explode(',', $dataRow['images'])) : 1; //這是判斷圖片欄位是否為空,下面會在合併時用到
1 //這是超連結的名稱顯示,不想直接顯示路徑顯示另外的名稱 2 $hyperlinkText = "打卡圖" . ($index + 1); 3 //先寫入再這是值為超連結 4 $worksheet->setCellValue($cellCoordinate, $hyperlinkText); 5 // 設定超連結 6 $worksheet->getCell($cellCoordinate)->getHyperlink()->setUrl(trim($image));
1 //除了圖片單元格外,其他的單元格列合併圖片所佔的行數 2 $worksheet->mergeCells($colIndex . $rowIndex . ':' . $colIndex . ($rowIndex + $maxImageCount - 1));
上面是設定超連結和合並的編寫內容,下面進行迴圈寫入excel,需要注意的是要在結果集的foreach外設定開始的行數,裡面進行設定開始的列;然後進行結果集的迴圈判斷圖片欄位,並且迴圈完後才能進行行數追加
1 $rowIndex = 2; 2 foreach ($dataList as $dataRow) { 3 $colIndex = 'A'; 4 $maxImageCount = !empty($dataRow['images']) ? count(explode(',', $dataRow['images'])) : 1; 5 6 foreach ($dataRow as $key => $value) { 7 $worksheet->getStyle($colIndex.$rowIndex)->getAlignment()->setWrapText(true); // 設定自動換行 8 9 if ($key == 'images' && !empty($value)) { 10 $imagePaths = explode(',', $value); 11 foreach ($imagePaths as $index => $image) { 12 //$worksheet->setCellValue($colIndex . ($rowIndex + $index), trim($image)); 13 $cellCoordinate = $colIndex . ($rowIndex + $index); 14 $hyperlinkText = "打卡圖" . ($index + 1); 15 $worksheet->setCellValue($cellCoordinate, $hyperlinkText); 16 // 設定超連結 17 $worksheet->getCell($cellCoordinate)->getHyperlink()->setUrl(trim($image)); 19 } 20 } else { 21 $worksheet->setCellValue($colIndex .$rowIndex, $value); 22 $worksheet->mergeCells($colIndex . $rowIndex . ':' . $colIndex . ($rowIndex + $maxImageCount - 1)); 23 } 24 $colIndex++; 25 } 27 $rowIndex += $maxImageCount; 28 }
寫入完畢後,再進行excel檔案的匯出 by user 悅悅 https://www.cnblogs.com/nuanai
1 header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'); 2 header('Content-Disposition: attachment;filename="'.$filename.date("Y-m-d",time()).'.xlsx"'); //檔名+當前時間命名,可以防止被覆蓋 3 header('Cache-Control: max-age=0'); 4 $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet); 5 $writer->save('php://output');
到這裡終於解決的圖片迴圈匯出的難題,還有一些excel的其他格式設定等,我沒有設定超連結的顏色等 by user 悅悅 https://www.cnblogs.com/nuanai
1 //預設B列隱藏 2 $worksheet->getColumnDimension('B')->setVisible(false); 3 4 // 將值以字串型別寫入單元格 5 $worksheet->setCellValueExplicit($titCol2.$i, $v, \PhpOffice\PhpSpreadsheet\Cell\DataType::TYPE_STRING);
by user 悅悅 https://www.cnblogs.com/nuanai