Laravel配合MaatwebsiteExcel实现Excel导出
相比导入,项目中导出场景更多,估摸着现在有十多个导出了,之前写了导入,这会才把导出补上。
安装之前说过,这里说一下配置,虽然已有默认配置,但还是有修改配置的场景,所以建议生成配置文件。
配置
//生成config/excel.php
php artisan vendor:publish --provider="Maatwebsite\Excel\ExcelServiceProvider"
配置只提一个,其他注释蛮细的,
'csv' => [
'delimiter' => ',',
'enclosure' => '"',
'line_ending' => PHP_EOL,
// 导出csv中文乱码,把use_bom设为true即可
'use_bom' => true,
'include_separator_line' => false,
'excel_compatibility' => false,
],
接下来,来完成一个导出的demo说明下常用的一些点。
DEMO
php artisan make:export MultiExport
生成文件如下:
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;
class MultiExport implements FromCollection
{
/**
* @return \Illuminate\Support\Collection
*/
public function collection()
{
//
}
}
- 自定义sheet,增加 WithTitle
- 自定义列名,增加WithHeadings
- 不想使用Collection,替换FromCollection使用FromArray
- 多个sheet,替换FromCollection使用WithMultipleSheets
经过改造:
<?php
/**
* 多重导出
*/
namespace App\Exports;
use App\Exports\MultiExportA;
use App\Exports\MultiExportB;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class MultiExport implements WithMultipleSheets
{
private $date;
public function __construct($date)
{
$this->date = $date;
}
public function sheets(): array
{
$sheets = [];
$sheets[] = new MultiExportA($this->date);
$sheets[] = new MultiExportB($this->date);
return $sheets;
}
}
---
// MultiExportA,MultiExportB类比即可
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithTitle;
use App\Models\ExportA;
class MultiExportA implements FromArray, WithTitle, WithHeadings
{
private $date;
public function __construct($date, $cityId)
{
$this->date = $date;
}
public function headings(): array
{
return [
'ID',
'名称',
'价格',
'手机'
];
}
/**
* @return array
*/
public function array() : array
{
$data = ExportA::where('date', $this->date)
->get()
->toArray();
$ret = [];
foreach ($data as $val) {
// 一段神奇的代码计算出了价格
$price = ...;
$ret[] = [
'id' => $val['id']."\t",
'name' => $val['name'],
'price' => $price,
// 转换为文本,编码excel使用了科学计数法
'mobile' => $val['mobile']."\t",
];
}
return $ret;
}
/**
* @return string
*/
public function title(): string
{
return '表格A';
}
}
使用
// 保存
$obj = new MultiExport($date);
Excel::store($obj, 'MultiExport'.$date.'.xlsx');
// 下载csv
Excel::download($obj, 'MultiExport'.$date.'.csv', \Maatwebsite\Excel\Excel::CSV, ['Content-Type' => 'text/csv']);
问题思考
当数据量过大的时候,导出时很可能会内存溢出了。建议:
- 使用其他高性能的组件,或者使用原生代码流式输出到浏览器,也可以直接使用其他语言(比如go)编写
- 文件过大,Excel打开大数据量文件也很鸡肋,容易卡死甚至崩溃,尝试分文件导出,比如1w一个文件
- 部分导出过程可能有计算,可以提前计算好,导出时直接读表,使用LazyCollection, 使用 Lazy Collections 来提高 Laravel Excel 读取的性能(轻松支持百万数据)
Laravel配合MaatwebsiteExcel实现Excel导出
https://blog.puresai.com/2020/08/31/272/