官方文档
https://docs.laravel-excel.com/3.1/getting-started/
GIT 地址
https://github.com/maatwebsite/Laravel-Excel
作为一个和 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 代码内容
<?phpnamespace 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 支持查询语句导出、数组导出、视图表格导出,这些可以具体查看文档。
我们通常情况下需要组装业务数据,集合导出可以作为通用的导出方案。
<?phpnamespace 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 表等功能。
单元格格式化
有时候我们需要对单元格处理文本、数字、日期、金额等格式。
<?phpnamespace App\Exports;use App\User;use Maatwebsite\Excel\Concerns\FromCollection;//新增两个 useuse PhpOffice\PhpSpreadsheet\Style\NumberFormat;use Maatwebsite\Excel\Concerns\WithColumnFormatting;//新增 WithColumnFormattingclass 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, //金额保留两位小数];}
自动适应单元格宽
<?phpnamespace App\Exports;use App\User;use Maatwebsite\Excel\Concerns\FromCollection;//新增use Maatwebsite\Excel\Concerns\ShouldAutoSize;//新增 ShouldAutoSizeclass UsersExport implements FromCollection, ShouldAutoSize{public function collection(){return User::all();}}
导出多 sheet
多表导出需要做两步操作,第一组装 sheet,第二生成对应的 sheet 表
<?phpnamespace App\Exports;use App\User;//新增use Maatwebsite\Excel\Concerns\Exportable;use Maatwebsite\Excel\Concerns\WithMultipleSheets;//新增 WithMultipleSheetsclass 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');}];}}
我没找到能全局处理的方式,如果你们知道请告诉我,万分感谢。
导出图片
<?phpnamespace 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;}
还有其他大家需要的功能可以补充在评论中,我会添加进来。
导入功能请期待下篇。
