Laravel Maatwebsite Excel 3.1:如何添加自定义表头与合计页脚?
搞定Laravel Excel(maatwebsite 3.1):自定义表头+金额合计页脚实现方案
我来帮你解决这个需求,正好对maatwebsite Excel 3.1版本的玩法很熟。你的现有代码已经能导出销售明细,但要加自定义表头和合计页脚,我们可以通过事件监听+PhpSpreadsheet底层操作来实现,下面一步步来:
先修正现有代码的小坑
先把你代码里的几个小问题补了,不然容易报错:
- 补上
RegistersEventListeners的命名空间引入(你之前漏了) - 把控制器的导出方法从Export类里挪出来——它本来就属于控制器(比如
SalesLogController),别混在Export类里
一、添加开头的自定义表头
这里的自定义表头指的是那种大标题(比如“XX飞机销售日志明细”),放在现有列头的上方。我们用AfterSheet事件来实现:
- 在数据列头上方插入新行
- 合并单元格放标题,再设置加粗、居中之类的样式
二、添加金额合计页脚
要做合计,得先算出所有明细的金额总和,然后在数据最后一行下面插合计行:
- 在Export类里存一个合计金额的属性
- 执行查询后计算总和
- 同样用
AfterSheet事件找到最后一行,插入合计行并设置样式
完整修改后的代码
1. SalesExport类(核心)
<?php namespace App\Exports; use App\SalesLog; use Maatwebsite\Excel\Concerns\FromQuery; use Maatwebsite\Excel\Concerns\Exportable; use Maatwebsite\Excel\Concerns\WithHeadings; use Maatwebsite\Excel\Concerns\ShouldAutoSize; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Concerns\RegistersEventListeners; use Maatwebsite\Excel\Events\AfterSheet; use PhpOffice\PhpSpreadsheet\Style\Alignment; use PhpOffice\PhpSpreadsheet\Style\Font; class SalesExport implements FromQuery, WithHeadings, ShouldAutoSize, WithEvents { use Exportable, RegistersEventListeners; protected $logId; protected $aircraftName; protected $totalAmount = 0; public function __construct($log_id, $aircraft_name) { $this->logId = $log_id; $this->aircraftName = $aircraft_name; } public function headings(): array { return [ '#No', 'Item Description', 'Unit Type', 'Item Price', ]; } public function query() { // 构建查询 $query = SalesLog::query() ->join('sales_log_items', 'sales_logs.id', '=', 'sales_log_items.sales_log_id') ->where('sales_log_items.sales_log_id', $this->logId) ->select( 'sales_log_items.product_id', 'sales_log_items.name', 'sales_log_items.unit_type', 'sales_log_items.price' ); // 计算总金额:先执行查询拿到集合,再求和 $this->totalAmount = $query->get()->sum('price'); return $query; } public function registerEvents(): array { return [ AfterSheet::class => function (AfterSheet $event) { $sheet = $event->sheet->getDelegate(); // --- 1. 添加自定义大表头 --- // 在第1行插入新行(原来的列头会往下移) $sheet->insertNewRowBefore(1, 1); // 合并A1到D1的单元格,放大标题 $sheet->mergeCells('A1:D1'); $sheet->setCellValue('A1', "{$this->aircraftName} 销售日志明细"); // 设置大标题样式:加粗、居中、字体放大 $sheet->getStyle('A1')->applyFromArray([ 'font' => [ 'bold' => true, 'size' => 16, ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_CENTER, ], ]); // --- 2. 添加金额合计行 --- // 获取当前Excel的最后一行(包含自定义表头、列头、数据) $lastRow = $sheet->getHighestRow(); // 在最后一行下面插一行放合计 $sheet->insertNewRowAfter($lastRow, 1); // 设置合计内容 $sheet->setCellValue('A' . ($lastRow + 1), '合计'); $sheet->mergeCells('A' . ($lastRow + 1) . ':C' . ($lastRow + 1)); $sheet->setCellValue('D' . ($lastRow + 1), $this->totalAmount); // 设置合计行样式:加粗,金额列右对齐 $sheet->getStyle('A' . ($lastRow + 1) . ':D' . ($lastRow + 1))->applyFromArray([ 'font' => [ 'bold' => true, ], 'alignment' => [ 'horizontal' => Alignment::HORIZONTAL_RIGHT, ], ]); // 单独把“合计”文字改成左对齐,更美观 $sheet->getStyle('A' . ($lastRow + 1))->getAlignment()->setHorizontal(Alignment::HORIZONTAL_LEFT); }, ]; } }
2. 控制器中的导出方法(比如SalesLogController)
public function exportSalesLog($log_id) { // 用findOrFail替代find,避免找不到日志时报错 $salesLog = SalesLog::findOrFail($log_id); $date = date('y-m-d'); // 文件名可以加航班号,更易识别 $excelTitle = "sales_log_{$date}_{$salesLog->flight_number_one}"; return (new SalesExport($log_id, $salesLog->aircraft_name))->download("{$excelTitle}.xlsx"); }
关键点解释
- 自定义表头:通过PhpSpreadsheet的
insertNewRowBefore插入行,mergeCells合并单元格,再用样式API美化标题 - 金额合计:先通过查询集合的
sum方法计算总金额,再找到数据最后一行插入合计行 - WithEvents:maatwebsite 3.1依赖事件监听来操作底层的PhpSpreadsheet对象,这是实现自定义Excel操作的核心方式
内容的提问来源于stack exchange,提问作者testerr testeerr
相关产品推荐
相关产品推荐

