laravel-excel maatwebsite/excel 新版中文文件
阿新 • • 發佈:2018-11-06
laravel 專案從 5.2 升級到了 5.7,Excel 的匯入匯出,使用的 maatwebsite/excel laravel-excel 依賴包,也從 2.* 升級到了 3.*,發現不能用了,開啟文件一看,這尼瑪改動也太大了吧,完全不能使用的節奏啊! 先分享幾個連結: github 地址: https://github.com/Maatwebsite/Laravel-Excel 官網地址: https://laravel-excel.maatwebsite.nl 看文件的升級指南,可以發現官方推薦了個連結,有人從 2.x 升級到 3.x,專案裡進行的程式碼修改 https://github.com/Maatwebsite/Laravel-Excel/issues/1799 PS: 想搜下新版的中文文件,開啟 google 搜尋,輸入 'maatwebsite/excel 中文文件',發現第 3 條居然是我之前寫的部落格,開啟一看,嚇我一跳,我尼瑪壓根沒有一點印象,之前居然總結過舊版文件,而且寫了 700 多行,有點吃驚,我以前居然這麼有耐心~ 好了,閒話少數,開始新版文件學習之旅~ 依賴: PHP: ^7.0 Laravel: ^5.5 PhpSpreadsheet: ^1.4 php_zip php_xml php_gd2 安裝: composer require maatwebsite/excel 配置: Maatwebsite\Excel\ExcelServiceProvider 預設是自動發現並註冊,我們也可以手動新增: config/app.php 'providers' => [ /* * Package Service Providers... */ Maatwebsite\Excel\ExcelServiceProvider::class, ] Excel 門面(Facade)也是自動發現,也可以手動新增: config/app.php 'aliases' => [ ... 'Excel' => Maatwebsite\Excel\Facades\Excel::class, ] 釋出配置檔案: php artisan vendor:publish 會建立 config/excel.php 匯出: 1.5分鐘快速入門: 在 App/Exports 下建立匯出類 php artisan make:export UsersExport --model=User UserExport.php 內容: <?php namespace App\Exports; use App\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'); } } 這樣就匯出了個 'users.xlsx' 檔案 2.匯出集合 匯出的最簡單方式是,建立一個自定義的匯出類。就是使用之前的命令,在 App/Exports 下建立一個匯出類 php artisan make:export UsersExport --model=User 1>常用方法 控制器裡下載: public function export() { return Excel::download(new InvoicesExport, 'invoices.xlsx'); } 控制器裡儲存到硬碟: public function storeExcel() { return Excel::store(new InvoicesExport, 'invoices.xlsx', 's3'); } 2>依賴注入: 另一種寫法,看文件 3>集合巨集: Laravel-Excel 為 Laravel 的匯出集合類,提供了一些巨集,更方便的下載和儲存集合。 下載: (new Collection([ [1, 'dongxuemin', 30], [2, 'yangyaping', 30]) )->downloadExcel($filePath, $writerType = null, $headings = false); 儲存: (new Collection([ [1, 'dongxuemin', 30], [2, 'yangyaping', 30]) )->storeExcel($filePath, $disk = null, $writerType = null, $headings = false); 總結: 我們可以自己利用 new Collection 來構造集合,進行下載和儲存 3.在硬碟上儲存匯出資料: 匯出可以很容易地被儲存到 Laravel 所支援的任意檔案系統。 1>不傳遞引數,預設檔案系統 Excel::store(new InvoicesExport(2018), 'invoices.xlsx'); 2>儲存到 's3' 檔案系統 Excel::store(new InvoicesExport(2018), 'invoices.xlsx', 's3'); 3>儲存到 's3' 檔案系統,並指定 'writer' 型別 Excel::store(new InvoicesExport(2018), 'invoices.xlsx', 's3', Excel::XLSX); 4.匯出格式: 預設情況下,匯出格式由匯出檔案的字尾決定,例如:'user.xlsx',匯出格式就是:\Maatwebsite\Excel\Excel::XLSX。我們也可以傳遞第二個引數,顯式地指定匯出格式。 (new InvoicesExport)->download('invoices.xlsx', \Maatwebsite\Excel\Excel::XLSX); 支援的格式有: XLSX CSV TSV ODS XLS SLK XML GNUMERIC HTML MPDF DOMPDF TCPDF 5.可匯出的 之前的方法中,我們使用 Excel::download 門面(Facade) 來匯出。 例如:在控制器中使用 Excel::download(new InvoicesExport(2018)); Laravel Excel 也提供了一個 'Maatwebsite\Excel\Concerns\Exportable' trait,使得我們建立的匯出類,本身具有可匯出的方法。 示例: use Maatwebsite\Excel\Concerns\Exportable; class InvoicesExport implements FromCollection { use Exportable; public function collection() { return Invoice::all(); } } 這樣,InvoicesExport 類本身就具有可匯出方法,不用再使用 Excel 門面(Facade) 下載: return (new InvoicesExport)->download('invoices.xlsx'); 儲存: return (new InvoicesExport)->store('invoices.xlsx', 's3'); 可響應: 可以使用 'Responsable' 介面,進一步簡化匯出操作。 use Illuminate\Contracts\Support\Responsable; class InvoicesExport implements FromCollection, Responsable { // 要求必須指定 'fileName' 屬性(匯出的檔名) private $fileName = 'invoices.xlsx'; } 下載: return new InvoicesExport(); 6.從查詢匯出 在之前的例子中,我們在匯出類中進行查詢。對於小型匯出,這個是一個非常好的解決方案,但是對於大型匯出,會有很大的效能開銷。 通過使用 'FromQuery',我們可以為匯出準備一個查詢。在底層,'FromQuery' 查詢使用了 chunks 查詢,以減少效能開銷。 普通查詢: 示例: use Maatwebsite\Excel\Concerns\FromQuery; // 引入 'FromQuery' class InvoicesExport implements FromQuery // 實現 'FromQuery' { use Exportable; public function query() { return Invoice::query(); // 確保不要使用 'get()' 方法 } } 下載: return (new InvoicesExport)->download('invoices.xlsx'); 自定義查詢 /* 這個應該是我們最經常使用的方法!!! 我們一般都是根據使用者的各種篩選條件,然後進行 query 查詢,然後得到最終的結果列表,再進行匯出。 但因為新版,匯出的資料結果,都是通過外部的匯出類來實現了,我們必須將 query 引數,傳遞到匯出類中,來獲取結果集。 */ 普通示例: use Maatwebsite\Excel\Concerns\FromQuery; // 引入 'FromQuery' class InvoicesExport implements FromQuery // 實現 'FromQuery' { use Exportable; public function __construct(int $year) // 匯入外部查詢引數 { $this->year = $year; } public function query() { return Invoice::query()->whereYear('created_at', $this->year); // 使用 where 查詢 } } 下載: // 傳遞查詢引數 return (new InvoicesExport(2018))->download('invoices.xlsx'); 設定器示例(另一種寫法): use Maatwebsite\Excel\Concerns\FromQuery; // 引入 'FromQuery' class InvoicesExport implements FromQuery // 實現 'FromQuery' { use Exportable; public function forYear(int $year) // 定義 '設定器' { $this->year = $year; return $this; } public function query() { return Invoice::query()->whereYear('created_at', $this->year); // 使用 where 查詢 } } 下載: // 呼叫 '設定器' return (new InvoicesExport)->forYear(2018)->download('invoices.xlsx'); 7.從模板中匯出 定義匯出類,同時定義一個匯出模板,Laravel Excel 會將定義的 HTML table 轉換為一個 Excel 電子表單 示例: 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() ]); } } Blade 模板,定義一個標準的 <table> 即可,<thead> - 表頭 & <tbody> - 表內容 <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> 8.佇列 如果處理大量的資料匯出,推薦使用佇列來進行匯出。 佇列匯出,底層實現是:使用 chunk 查詢,多個 job 任務連結在一起(應該是按順序連結)。這些 job 任務以插入佇列的先後順序正確執行,只有當前面的任務執行成功,後面的才會執行。 普通示例: 匯出類定義一致 下載,直接呼叫 'queue()' 方法 (new InvoicesExport)->queue('invoices.xlsx'); return back()->withSuccess('Export started!'); 顯示定義匯出到佇列 use Maatwebsite\Excel\Concerns\FromQuery; use Illuminate\Contracts\Queue\ShouldQueue; // 引入 'ShouldQueue' class InvoicesExport implements FromQuery, ShouldQueue // 實現 'ShouldQueue' { use Exportable; public function query() { return Invoice::query(); } } 下載,使用 'store()' 方法 (new InvoicesExport)->store('invoices.xlsx'); 追加佇列任務 queue() 方法返回 Laravel 的 'PendingDispatch' 例項。意味著,我們可以在佇列尾部新增額外的 job 任務,新新增的匯出任務,只有在之前的匯出都正確後,才會執行。 示例: use Illuminate\Bus\Queueable; // 引入 'Queueable' use Illuminate\Contracts\Queue\ShouldQueue; use Illuminate\Queue\SerializesModels; // 引入 'SerializesModels' class NotifyUserOfCompletedExport implements ShouldQueue { use Queueable, SerializesModels; // 使用 'Queueable' & 'SerializesModels' public $user; public function __construct(User $user) // 傳遞引數 { $this->user = $user; } public function handle() // 呼叫了 'handle()' 方法 { $this->user->notify(new ExportReady()); } } 追加: (new InvoicesExport)->queue('invoices.xlsx')->chain([ new NotifyUserOfCompletedExport(request()->user()), // 傳遞引數 ]); 自定義佇列: 由於返回了 'PendingDispatch',我們也可以更改使用的佇列。(有時間可看下 PendingDispatch 原始碼) (new InvoicesExport)->queue('invoices.xlsx')->allOnQueue('exports'); 9.多個表單 多表單的匯出,需要使用 'WithMultipleSheets'。然後在匯出類中,實現 'sheets()' 方法,sheets() 方法,返回一個由 '單個表單物件' 組成的陣列。 多表單的匯出,需要2個類: 1>匯出類 2>單個表單類 示例: 1>匯出類 use Maatwebsite\Excel\Concerns\WithMultipleSheets; class InvoicesExport implements WithMultipleSheets { // 實現 sheets() 方法,返回一個由 '單個表單物件' 組成的陣列。 public function sheets(): array { $sheets = []; for ($month = 1; $month <= 12; $month++) { $sheets[] = new InvoicesPerMonthSheet($this->year, $month); } return $sheets; } } 2>單個表單類,可以實現 'FromQuery','FromCollection',... use Maatwebsite\Excel\Concerns\FromQuery; // 引入 'FromQuery' use Maatwebsite\Excel\Concerns\WithTitle; // 引入 'WithTitle'(可修改 excel 表單名) class InvoicesPerMonthSheet implements FromQuery, WithTitle { // 查詢 public function query() { return Invoice ::query() ->whereYear('created_at', $this->year) ->whereMonth('created_at', $this->month); } // Excel 電子表單名 public function title(): string { return 'Month ' . $this->month; } } 10.對映資料 對映行 新增 'WithMapping',我們可以定義一個 'map()' 方法,將查詢到的每條資料,經過 map() 方法處理,返回我們需要的 '一整行'。 示例: use Maatwebsite\Excel\Concerns\WithMapping; // 引入 'WithMapping' class InvoicesExport implements FromQuery, WithMapping // 實現 'WithMapping' // 定義 'map()' 方法,引數是 '查詢出來的每行資料物件' public function map($invoice): array { return [ $invoice->invoice_number, Date::dateTimeToExcel($invoice->created_at), ]; } } 新增標題行 新增 'WithHeadings',定義 'headings()' 方法,來新增標題行 示例: use Maatwebsite\Excel\Concerns\WithHeadings; // 引入 'WithHeadings' class InvoicesExport implements FromQuery, WithHeadings // 實現 'WithHeadings' // 定義 'headings()' 方法 public function headings(): array { return [ '#', 'Date', ]; } } 11.格式化列 使用 'WithColumnFormatting',定義 'columnFormats()' 方法,我們可以輕鬆格式化整列資料。 如果想要更多自定義內容,建議使用 AfterSheet 事件直接與底層 Worksheet 類進行互動。 示例: use PhpOffice\PhpSpreadsheet\Shared\Date; // 日期處理 use PhpOffice\PhpSpreadsheet\Style\NumberFormat; // 數字格式化 use Maatwebsite\Excel\Concerns\WithColumnFormatting; // 引入 '列格式化' use Maatwebsite\Excel\Concerns\WithMapping; class InvoicesExport implements WithColumnFormatting, WithMapping { public function map($invoice): array { return [ $invoice->invoice_number, Date::dateTimeToExcel($invoice->created_at), $invoice->total ]; } /** * @return array */ public function columnFormats(): array { return [ 'B' => NumberFormat::FORMAT_DATE_DDMMYYYY, 'C' => NumberFormat::FORMAT_CURRENCY_EUR_SIMPLE, ]; } } 日期處理: 推薦在 map() 方法中使用 '\PhpOffice\PhpSpreadsheet\Shared\Date::dateTimeToExcel()' 自動調整尺寸: 引入 'ShouldAutoSize',讓 Laravel Excel 自動調整單元格寬度 use Maatwebsite\Excel\Concerns\ShouldAutoSize; Class InvoicesExport implements ShouldAutoSize { } 12.提供的所有可用的 'Export concerns' 介面: Maatwebsite\Excel\Concerns\FromArray - 使用 array 來實現匯出 Maatwebsite\Excel\Concerns\FromCollection - 使用 Laravel collection 來實現匯出 Maatwebsite\Excel\Concerns\FromIterator - 使用 iterator(迭代器)來實現匯出 Maatwebsite\Excel\Concerns\FromQuery - 使用 Eloquent query 來實現匯出 Maatwebsite\Excel\Concerns\FromView - 使用 (Blade) 模板來實現匯出 Maatwebsite\Excel\Concerns\WithTitle - 設定工作簿或工作表標題 Maatwebsite\Excel\Concerns\WithHeadings - 新增表頭 Maatwebsite\Excel\Concerns\WithMapping - 在寫入檔案前,格式化行 Maatwebsite\Excel\Concerns\WithColumnFormatting - 格式化列 Maatwebsite\Excel\Concerns\WithMultipleSheets - 開啟多表單支援 Maatwebsite\Excel\Concerns\ShouldAutoSize - 在工作表中,自動調整列寬 Maatwebsite\Excel\Concerns\WithStrictNullComparison - 在測試單元格的 null 時,使用嚴格比較 Maatwebsite\Excel\Concerns\WithEvents - 註冊事件,掛載到 'PhpSpreadsheet' 處理過程中 Maatwebsite\Excel\Concerns\WithCustomQuerySize - 允許 'Exportable' 實現 'FromQuery',來提供它們自己的自定義查詢大小。 Maatwebsite\Excel\Concerns\WithCustomCsvSettings - 允許對指定的匯出,執行自定義的 CSV 設定。 Maatwebsite\Excel\Concerns\WithCharts - 允許執行一個或多個 PhpSpreadsheet Chart 例項 Maatwebsite\Excel\Concerns\WithDrawings - 允許執行一個或多個 PhpSpreadsheet Drawing 例項 Maatwebsite\Excel\Concerns\WithCustomStartCell - 允許指定一個自定義起始單元格。注意:僅支援 'FromCollection' 匯出 Traits: Maatwebsite\Excel\Concerns\Exportable - 給匯出類自身新增 'download()' 和 'store()' 方法 Maatwebsite\Excel\Concerns\RegistersEventListeners 13.擴充套件 有點複雜,不總結了,看文件 匯入: 匯出寫的有點累了,有時間再完善...