Laravel 8中Maatwebsite\Excel 3.1导出代码改写求助
将Laravel Excel旧版本代码适配为3.1版本
1. 创建导出类
在app/Exports目录下创建InstanceExport.php文件(若目录不存在则手动创建),内容如下:
<?php namespace App\Exports; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Concerns\WithMapping; use Maatwebsite\Excel\Concerns\WithChunkReading; class InstanceExport implements FromQuery, WithHeadings, WithMapping, WithChunkReading { protected $requested; protected $query; public function __construct(array $requested, $query) { $this->requested = $requested; $this->query = $query; } // 返回查询构建器 public function query() { return $this->query; } // 自定义表头 public function headings(): array { $columns = []; foreach ($this->requested as $column) { switch ($column) { case 'sku': $columns[] = 'SKU'; break; case 'material_name': $columns[] = 'Material Name'; break; case 'new_or_used': $columns[] = 'NEW OR USED'; break; case 'barcode': $columns[] = 'BARCODE'; break; case 'asset_or_sale': $columns[] = 'ASSET OR SALE'; break; case 'cost': $columns[] = 'COST'; break; case 'last_stock': $columns[] = 'LAST STOCK'; break; default: $columns[] = strtoupper($column); break; } } return $columns; } // 映射每行数据 public function map($instance): array { $row = []; $locale = app()->getLocale(); foreach ($this->requested as $column) { switch ($column) { case 'sku': $row[] = '[' . (string)$instance->sku . ']'; break; case 'material_name': $row[] = empty($instance->Material) ? '------' : (string)$instance->Material->{"name_$locale"}; break; case 'new_or_used': $row[] = $instance->is_new == 'Y' ? 'NEW' : 'secondhand'; break; case 'barcode': $row[] = '[' . (string)$instance->barcode . ']'; break; case 'asset_or_sale': $row[] = $instance->is_asset == 'Y' ? 'ASSET' : ' not asset'; break; case 'cost': $row[] = (string)round($instance->cost_of_good_sold, 2); break; case 'last_stock': if (empty($instance->LastOrderEntry)) { $row[] = '------'; } else { $row[] = $instance->LastOrderEntry->Stock ? (string)$instance->LastOrderEntry->Stock->{"name_$locale"} : '------'; } break; default: $row[] = '------'; break; } } return $row; } // 设置分块大小,和旧代码保持一致 public function chunkSize(): int { return 500; } }
2. 修改控制器中的导出代码
替换原有的闭包导出逻辑,改为调用导出类:
ini_set("memory_limit", "-1"); $requested = (array) $request->columns_to_export; // 预加载关联模型优化性能(可选) $query = $this->data['query']->with(['Material', 'LastOrderEntry.Stock']); return Excel::download(new \App\Exports\InstanceExport($requested, $query), 'instances-' . date('Y-m-d') . '.xlsx');
关键改动说明
- 3.1版本采用导出类模式替代旧版闭包写法,贴合Laravel面向对象设计
- 通过
WithChunkReading接口自动实现分块查询,无需手动调用chunk()方法 - 拆分表头和行数据逻辑到
WithHeadings、WithMapping接口,代码结构更清晰 - 修正旧代码中的拼写错误(
Material Nmae→Material Name、ASSEST OR SALE→ASSET OR SALE) - 可选预加载关联模型,避免N+1查询,提升导出效率
内容的提问来源于stack exchange,提问作者OMAR R A SHAIKHOMAR
相关产品推荐
相关产品推荐

