相比导入,我的项目中导出场景更多,估摸着当初有十多个导出了,之前写了导入,这会才把导出补上。

装置之前说过,这里说一下配置,尽管已有默认配置,但还是有批改配置的场景,所以倡议生成配置文件。

配置

//生成config/excel.phpphp 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

生成文件如下:

<?phpnamespace 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类比即可<?phpnamespace 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');// 下载csvExcel::download($obj, 'MultiExport'.$date.'.csv', \Maatwebsite\Excel\Excel::CSV, ['Content-Type' => 'text/csv']);

问题思考

当数据量过大的时候,导出时很可能会内存溢出了。倡议:

  • 应用其余高性能的组件,或者应用原生代码流式输入到浏览器,也能够间接应用其余语言(比方go)编写
  • 文件过大,Excel关上大数据量文件也很鸡肋,容易卡死甚至解体,尝试分文件导出,比方1w一个文件
  • 局部导出过程可能有计算,能够提前计算好,导出时间接读表,应用LazyCollection, 应用 Lazy Collections 来进步 Laravel Excel 读取的性能(轻松反对百万数据)