官方文件
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\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\User;
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\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\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\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;
}
還有其他大家需要的功能可以補充在評論中,我會新增進來。
匯入功能請期待下篇。