相比导入,项目中导出场景更多,估摸着现在有十多个导出了,之前写了导入,这会才把导出补上。
安装之前说过,这里说一下配置,虽然已有默认配置,但还是有修改配置的场景,所以建议生成配置文件。
配置
//生成config/excel.php php artisan vendor:publish --provider="MaatwebsiteExcelExcelServiceProvider"
配置只提一个,其他注释蛮细的,
'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 AppExports; use MaatwebsiteExcelConcernsFromCollection; class MultiExport implements FromCollection { /** * @return IlluminateSupportCollection */ public function collection() { // } }
- 自定义 sheet,增加 WithTitle
- 自定义列名,增加 WithHeadings
- 不想使用 Collection,替换 FromCollection 使用 FromArray
- 多个 sheet,替换 FromCollection 使用 WithMultipleSheets
经过改造:
<?php /** * 多重导出 */ namespace AppExports; use AppExportsMultiExportA; use AppExportsMultiExportB; use MaatwebsiteExcelConcernsWithMultipleSheets; 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 AppExports; use MaatwebsiteExcelConcernsFromArray; use MaatwebsiteExcelConcernsWithHeadings; use MaatwebsiteExcelConcernsWithTitle; use AppModelsExportA; 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', MaatwebsiteExcelExcel::CSV, ['Content-Type' => 'text/csv']);
问题思考
当数据量过大的时候,导出时很可能会内存溢出了。建议:
- 使用其他高性能的组件,或者使用原生代码流式输出到浏览器,也可以直接使用其他语言(比如 go)编写
- 文件过大,Excel 打开大数据量文件也很鸡肋,容易卡死甚至崩溃,尝试分文件导出,比如 1w 一个文件
- 部分导出过程可能有计算,可以提前计算好,导出时直接读表,使用 LazyCollection, 使用 Lazy Collections 来提高 laravel Excel 读取的性能(轻松支持百万数据)
© 版权声明
文章版权归作者所有,未经允许请勿转载。
THE END
喜欢就支持以下吧