Laravel Excel 匯出精美的excel圖文檔案
本篇文章以一個需求案例提供方向給需要匯出Excel的朋友參考,內文不會詳細說明文件細項,只針對有用到的method說明
參考連結
https://docs.laravel-excel.com/3.0/exports/collection.html
https://phpoffice.github.io/PhpSpreadsheet/1.4.1/PhpOffice/PhpSpreadsheet/Worksheet/Drawing.html
https://laracasts.com/discuss/channels/laravel/storing-image-file-retrieved-from-external-url?page=1
https://laraveldaily.com/laravel-excel-export-formatting-and-styling-cells/
https://phpspreadsheet.readthedocs.io/en/latest/topics/recipes/#setting-a-columns-width
案例需求:
- 將資料匯出到excel須包含圖片以及文字
- 必須設定圖片大小與cell大小
- 要匯出的圖片只有url link並不存在伺服器端
一. 透過Laravel Excel 匯出資料
根據官網提供的步驟如下
透過composer安裝 Laravel Excel
1 |
composer require maatwebsite/excel |
在config/app.php中加入provider 以及Alias
1 2 3 4 5 6 7 8 9 10 11 |
'providers' => [ /* * Package Service Providers... */ Maatwebsite\Excel\ExcelServiceProvider::class, ] 'aliases' => [ ... 'Excel' => Maatwebsite\Excel\Facades\Excel::class, ] |
最後,publish config
1 |
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider" |
二. 匯出一個基本的excel資料
Laravel Excel 提供多種快速的匯出功能,本次介紹最容易上手的From View
From View,共名思義就是透過view blade的表格資料直接mapping到excel table中
在App\Exports 建立一個匯出資料的class
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
namespace App\Exports; use Illuminate\Contracts\View\View; use Maatwebsite\Excel\Concerns\FromView; class InvoicesExport implements FromView { public function view(): View { return view('exports.invoices', [ 'invoices' => Invoice::all() ]); } } |
簡單說明就是透過Invoice Eloquent取出所有資料,並且放入export.invoice view中
接著在 resource\view\export 中建立invoice.blade.php,用來顯示資料
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 |
<table> <thead> <tr> <th>Name</th> <th>Email</th> </tr> </thead> <tbody> @foreach($users as $user) <tr> <td>{{ $user->name }}</td> <td>{{ $user->email }}</td> </tr> @endforeach </tbody> </table> |
內容其實就是一般的view blade
資料與view都準備好之後就可以在controller中呼叫來下載了
1 2 3 4 5 6 7 8 9 10 11 |
use App\Exports\UsersExport; use Maatwebsite\Excel\Facades\Excel; use App\Http\Controllers\Controller; class UsersController extends Controller { public function export() { return Excel::download(new InvoicesExport, 'invoice.xlsx'); } } |
在usercontroller中呼叫Excel::download,並且new InvoicesExport Class,第二個參數是指定下載的檔案名稱
到目前為止已經透過 Laravel Excel 間單的匯出了資料
三. 透過Drawing 匯出圖片到excel中,並且設定好cell長寬
要在excel中插入圖片必須透過PhpSpreadsheet的Drawing 將圖片繪入
範例如下
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 |
public function registerEvents():array { return [ AfterSheet::class => function(AfterSheet $event){ $drawing = new \PhpOffice\PhpSpreadsheet\Worksheet\Drawing(); $drawing->setName('submit_img'); $drawing->setDescription('submit_img'); $drawing->setPath(storage_path('001.jpg')); $drawing->setWidth('500'); $drawing->setOffsetX('10'); $drawing->setOffsetY('10'); $drawing->setCoordinates('C1'); //設定高度 $event->sheet->getRowDimension(2)->setRowHeight($drawing->getHeight()); $drawing->setWorksheet($event->sheet->getDelegate()); //調整欄位寬度 $event->sheet->getColumnDimension('A')->setWidth(5); $event->sheet->getColumnDimension('B')->setWidth(18); $event->sheet->getColumnDimension('C')->setWidth(70); }, ]; } |
簡單說明一下邏輯,首先我們在第二部分撰寫的InvoicesExport class中必須新增一個function “registerEvents”,用來調整excel的內容,並且透過AfterSheet 來控制sheet中cell的大小、顏色、邊筐等等設定
接著針對幾個設定項目來做說明
1 2 3 4 5 6 7 8 9 10 11 12 13 14 |
$drawing->setPath(storage_path('001.jpg')); //設定圖片的位置,範例是將圖片放在storage\app\001.jpg $drawing->setWidth('500'); //設定圖片寬度 $drawing->setOffsetX('10'); //設定圖片距離cell邊界位移 $drawing->setOffsetY('10'); //設定圖片距離cell邊界位移 $drawing->setCoordinates('C1'); //設定圖片要放在哪個cell上 $event->sheet->getRowDimension(2)->setRowHeight($drawing->getHeight()); //設定第二行行高為圖片的高度 $event->sheet->getColumnDimension('A')->setWidth(5); //設定A column寬度為5 |
**注意**
registerEvents 執行時間會在view 之前,所以無法在view中先整理好資料邏輯再由registerEvents來排列excel規格
四. 遠端圖片該如何插入Excel中
Drawing只能插入本地端的圖片,但是本次任務是將遠端圖片插入excel中,因此必須先下載圖片儲存後才能插入excel中
1 2 3 |
$contents = file_get_contents($url); $name = '001.jpg'; Storage::put($name, $contents); |
其實只要透過file_get_contents,去得遠端內容後,再透過Storage就可以輕鬆地將圖片儲存在本地端
透過Storage::pu,檔案會儲存在Storage\app 中
串連以上,就可以透過 Laravel Excel 將遠端圖片插入到excel sheet的指定cell中了!