maatwebsite/Excel 3.1 使用教程 (导出篇)
官方文档
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 AppExports;
use AppUser;
use MaatwebsiteExcelConcernsFromCollection;
class UsersExport implements FromCollection
{
public function collection()
{
return User::all();
}
}
业务控制器中调用
use AppExportsUsersExport;
use MaatwebsiteExcelFacadesExcel;
use AppHttpControllersController;
class UsersController extends Controller
{
public function export()
{
return Excel::download(new UsersExport, “users.xlsx”);
}
}
很方便简单是不是。这样可以把 user 表中所有内容都导入 excel 。很显然你的业务不会如此简单,那就继续。
Laravel Excel 支持查询语句导出、数组导出、视图表格导出,这些可以具体查看文档。
我们通常情况下需要组装业务数据,集合导出可以作为通用的导出方案。
<?php
namespace AppExports;
use AppUser;
use MaatwebsiteExcelConcernsFromCollection;
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 AppExports;
use AppUser;
use MaatwebsiteExcelConcernsFromCollection;
//新增两个 use
use PhpOfficePhpSpreadsheetStyleNumberFormat;
use MaatwebsiteExcelConcernsWithColumnFormatting;
//新增 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 AppExports;
use AppUser;
use MaatwebsiteExcelConcernsFromCollection;
//新增
use MaatwebsiteExcelConcernsShouldAutoSize;
//新增 ShouldAutoSize
class UsersExport implements FromCollection, ShouldAutoSize
{
public function collection()
{
return User::all();
}
}
导出多 sheet
多表导出需要做两步操作,第一组装 sheet,第二生成对应的 sheet 表
<?php
namespace AppExports;
use AppUser;
//新增
use MaatwebsiteExcelConcernsExportable;
use MaatwebsiteExcelConcernsWithMultipleSheets;
//新增 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 AppExports;
use MaatwebsiteExcelConcernsFromQuery;
use MaatwebsiteExcelConcernsWithTitle;
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 AppExports;
use MaatwebsiteExcelConcernsWithEvents;
use MaatwebsiteExcelEventsBeforeExport;
use MaatwebsiteExcelEventsBeforeWriting;
use MaatwebsiteExcelEventsBeforeSheet;
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 AppExports;
//新增
use MaatwebsiteExcelConcernsWithDrawings;
use PhpOfficePhpSpreadsheetWorksheetDrawing;
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;
}
还有其他大家需要的功能可以补充在评论中,我会添加进来。
导入功能请期待下篇。