官方文檔
https://docs.laravel-excel.com/3.1/getting...
GIT 地址
https://github.com/maatwebsite/Laravel-Exc...
作為一個和 laravel 契合度很高的 excel 工具包,大家應該都是用過這個工具。特別是 2.x
版本幾乎是用 laravel 框架都接觸過,3.x
基本上全部重構,全網幾乎找不到比較完善的教程,我就先拋磚引玉,大概把我用到的功能使用方式列一下,歡迎大家補充。
環境要求
PHP: ^7.0
Laravel: ^5.5
安裝方式
composer require maatwebsite/excel
因為目前 3.1 只支持 Laravel 5.5 以上,所以會自動注冊。
excel 導出
新建導出文件,導入導出業務代碼盡量不要和原來業務耦合。我們拿官網 user 模塊舉例
php artisan make:export UsersExport --model=User
會在 app 目錄下創建 Exports 目錄
. ├── app │ ├── Exports │ │ ├── UsersExport.php │ └── composer.json
UsersExport.php 代碼內容
<?php namespace App\Exports; use App\Models\User; use Maatwebsite\Excel\Concerns\FromCollection; class UsersExport implements FromCollection { public function collection() { return User::all(); } }
業務控制器中調用
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 UsersExport, 'users.xlsx'); } }
很方便簡單是不是。這樣可以把 user 表中所有內容都導入 excel 。很顯然你的業務不會如此簡單,那就繼續。
Laravel Excel 支持查詢語句導出、數組導出、視圖表格導出,這些可以具體查看文檔。
我們通常情況下需要組裝業務數據,集合導出可以作為通用的導出方案。
<?php namespace App\Exports; use App\Models\User; use Illuminate\Support\Collection; use Maatwebsite\Excel\Concerns\FromCollection; class UsersExport implements FromCollection { protected $data; //構造函數傳值 public function __construct($data) { $this->data = $data; } //數組轉集合 public function collection() { return new Collection($this->createData()); } //業務代碼 public function createData() { //todo 業務 } }
createData 方法返回的數據格式如下
return [ ['編號', '姓名', '年齡'] [1, '小明', '18歲'], [4, '小紅', '17歲'] ];
需要注意的是,這里組裝了 excel 的表頭,這也是比較方便的地方。
如此,簡單的業務導出就完成了,應該可以滿足 80% 需求,接下來我們繼續,比如單元格格式化、自動適應、設置寬高、導出圖片、多 sheet 表等功能。
單元格格式化
有時候我們需要對單元格處理文本、數字、日期、金額等格式。
<?php namespace App\Exports; use App\Models\User; use Maatwebsite\Excel\Concerns\FromCollection; //新增兩個 use use PhpOffice\PhpSpreadsheet\Style\NumberFormat; use Maatwebsite\Excel\Concerns\WithColumnFormatting; //新增 WithColumnFormatting class UsersExport implements FromCollection, WithColumnFormatting { public function collection() { return User::all(); } } /** * @return array */ public function columnFormats(): array { return [ 'B' => NumberFormat::FORMAT_DATE_DDMMYYYY, //日期 'C' => NumberFormat::FORMAT_NUMBER_00, //金額保留兩位小數 ]; }
自動適應單元格寬
<?php namespace App\Exports; use App\Models\User; use Maatwebsite\Excel\Concerns\FromCollection; //新增 use Maatwebsite\Excel\Concerns\ShouldAutoSize; //新增 ShouldAutoSize class UsersExport implements FromCollection, ShouldAutoSize { public function collection() { return User::all(); } }
導出多 sheet
多表導出需要做兩步操作,第一組裝 sheet,第二生成對應的 sheet 表
<?php namespace App\Exports; use App\Models\User; //新增 use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\WithMultipleSheets; //新增 WithMultipleSheets class UsersExport implements WithMultipleSheets { use Exportable; protected $year; public function __construct(int $year) { $this->year = $year; } /** * @return array */ public function sheets(): array { $sheets = []; for ($month = 1; $month <= 12; $month++) { //不同的數據可以調用不同的方法 $sheets[] = new UserPerMonthSheet($this->year, $month); } return $sheets; } }
然后新建 UserPerMonthSheet 類
namespace App\Exports; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithTitle; class UserPerMonthSheet implements FromQuery, WithTitle { private $month; private $year; public function __construct(int $year, int $month) { $this->month = $month; $this->year = $year; } /** * @return Builder */ public function query() { return User ::query() ->whereYear('created_at', $this->year) ->whereMonth('created_at', $this->month); } /** * sheet 表名稱 * @return string */ public function title(): string { return 'Month ' . $this->month; } }
設置單元格高度以及垂直居中,字體顏色、背景色等
這里需要用到 Laravel Excel 的事件模塊
提供多種事件 BeforeExport、BeforeWriting、BeforeSheet,AfterSheet 等等,也就是導出功能的生命周期,具體查看文檔即可。修改單元格高度我們這里使用 AfterSheet
namespace App\Exports; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\BeforeExport; use Maatwebsite\Excel\Events\BeforeWriting; use Maatwebsite\Excel\Events\BeforeSheet; class UserExport implements WithEvents { /** * 注冊事件 * @return array */ public function registerEvents(): array { return [ AfterSheet::class => function(AfterSheet $event) { //設置作者 $event->writer->setCreator('Patrick'); //設置列寬 $event->sheet->getDelegate()->getColumnDimension('A')->setWidth(50); //設置行高,$i為數據行數 for ($i = 0; $i<=1265; $i++) { $event->sheet->getDelegate()->getRowDimension($i)->setRowHeight(50); } //設置區域單元格垂直居中 $event->sheet->getDelegate()->getStyle('A1:K1265')->getAlignment()->setVertical('center'); //設置區域單元格字體、顏色、背景等,其他設置請查看 applyFromArray 方法,提供了注釋 $event->sheet->getDelegate()->getStyle('A1:K6')->applyFromArray([ 'font' => [ 'name' => 'Arial', 'bold' => true, 'italic' => false, 'strikethrough' => false, 'color' => [ 'rgb' => '808080' ] ], 'fill' => [ 'fillType' => 'linear', //線性填充,類似漸變 'rotation' => 45, //漸變角度 'startColor' => [ 'rgb' => '000000' //初始顏色 ], //結束顏色,如果需要單一背景色,請和初始顏色保持一致 'endColor' => [ 'argb' => 'FFFFFF' ] ] ]); //合並單元格 $event->sheet->getDelegate()->mergeCells('A1:B1'); } ]; } }
我沒找到能全局處理的方式,如果你們知道請告訴我,萬分感謝。
導出圖片
<?php namespace App\Exports; //新增 use Maatwebsite\Excel\Concerns\WithDrawings; use PhpOffice\PhpSpreadsheet\Worksheet\Drawing; class UserExport implements WithDrawings { public function drawings() { $drawing = new Drawing(); $drawing->setName('Logo'); $drawing->setDescription('This is my logo'); $drawing->setPath(public_path('/img/logo.jpg')); $drawing->setHeight(50); $drawing->setCoordinates('B3'); $drawing2 = new Drawing(); $drawing2->setName('Other image'); $drawing2->setDescription('This is a second image'); $drawing2->setPath(public_path('/img/other.jpg')); $drawing2->setHeight(120); $drawing2->setCoordinates('G2'); return [$drawing, $drawing2]; } }
這是官方的例子,實際使用中我們不可能手寫這么多方法塊,我改寫一下
public function drawings() { //這里的數據自己組裝 $draw_arr = [1 =>'detail1.jpg', 2 => 'detail2.jpg']; $result = []; foreach ($draw_arr as $k => $v) { ${'drawing'.$k} = new Drawing(); ${'drawing'.$k}->setName('Other image'); ${'drawing'.$k}->setDescription('This is a second image'); //圖片路徑 ${'drawing'.$k}->setPath(public_path($v)); ${'drawing'.$k}->setHeight(50); //設置圖片列 ${'drawing'.$k}->setCoordinates('U'.$k); $result[] = ${'drawing'.$k}; } return $result; }
maatwebsite/Excel 3.1 使用教程 (導出篇) - Laravel實戰 - E度筆記
http://www.edbiji.com/doccenter/showdoc/209/nav/3722.html