Laravel6 配合 MaatwebsiteExcel 实现 Excel 导出

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

安装之前说过,这里说一下配置,虽然已有默认配置,但还是有修改配置的场景,所以建议生成配置文件。

配置

//生成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
喜欢就支持以下吧
点赞0
分享
评论 抢沙发