You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Laravel Excel导出合并列表头实现求助

Laravel Excel 合并列表头实现方案

所有逻辑完全在Export类中处理,控制器仅负责传递参数和触发导出操作。以下是具体实现步骤:

1. Export类核心实现

先引入必要依赖,通过构造函数接收前端下拉框数据,再通过BeforeSheet事件完成表头合并、内容填充和样式设置:

<?php

namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeSheet;
use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
use PhpOffice\PhpSpreadsheet\Style\Alignment;
use App\Models\Month;

class YourExport implements FromCollection, WithHeadings, WithEvents
{
    protected $dropdownData;

    // 接收前端下拉框数据
    public function __construct($dropdownData)
    {
        $this->dropdownData = $dropdownData;
    }

    // 原有数据集合(你的业务数据)
    public function collection()
    {
        return \App\Models\YourModel::all();
    }

    // 原有A-Z列的基础表头
    public function headings(): array
    {
        return ['列A', '列B', '列C', ..., '列Z'];
    }

    // 注册Excel事件处理表头逻辑
    public function registerEvents(): array
    {
        return [
            BeforeSheet::class => function(BeforeSheet $event) {
                $sheet = $event->sheet;
                $months = Month::pluck('name')->toArray(); // 从数据库取月份数据
                $dropdownItems = $this->dropdownData;

                // 插入2行空白行,避免覆盖原有A-Z2行及下方数据
                $sheet->insertNewRowBefore(1, 2);

                // 第一行:合并单元格的月份表头(从D1开始)
                $startCol = 'D';
                $currentCol = $startCol;
                foreach ($months as $month) {
                    // 计算当前月份对应的12列结束位置
                    $currentColIndex = Coordinate::columnIndexFromString($currentCol);
                    $endColIndex = $currentColIndex + 11;
                    $endCol = Coordinate::stringFromColumnIndex($endColIndex);

                    // 合并单元格
                    $sheet->mergeCells("{$currentCol}1:{$endCol}1");
                    // 设置月份名称
                    $sheet->setCellValue("{$currentCol}1", $month);
                    // 设置样式:居中+加粗
                    $sheet->getStyle("{$currentCol}1:{$endCol}1")->applyFromArray([
                        'alignment' => [
                            'horizontal' => Alignment::HORIZONTAL_CENTER,
                            'vertical' => Alignment::VERTICAL_CENTER,
                        ],
                        'font' => [
                            'bold' => true,
                            'size' => 12,
                        ],
                    ]);

                    // 切换到下一个月份的起始列
                    $currentCol = Coordinate::stringFromColumnIndex($endColIndex + 1);
                }

                // 第二行:下拉框数据循环12次填充(从D2开始)
                $currentCol = $startCol;
                foreach ($dropdownItems as $item) {
                    for ($i = 0; $i < 12; $i++) {
                        $sheet->setCellValue("{$currentCol}2", $item);
                        // 设置样式:居中+加粗
                        $sheet->getStyle("{$currentCol}2")->applyFromArray([
                            'alignment' => [
                                'horizontal' => Alignment::HORIZONTAL_CENTER,
                            ],
                            'font' => [
                                'bold' => true,
                            ],
                        ]);
                        // 切换到下一列
                        $currentCol = Coordinate::stringFromColumnIndex(Coordinate::columnIndexFromString($currentCol) + 1);
                    }
                }

                // 设置列宽,适配内容
                $totalColumns = count($months) * 12;
                $startColIndex = Coordinate::columnIndexFromString($startCol);
                for ($i = $startColIndex; $i < $startColIndex + $totalColumns; $i++) {
                    $sheet->getColumnDimension(Coordinate::stringFromColumnIndex($i))->setWidth(10);
                }
            },
        ];
    }
}

2. 控制器调用

控制器只需接收前端下拉框数据,传递给Export类并触发导出:

<?php

namespace App\Http\Controllers;

use Illuminate\Http\Request;
use Maatwebsite\Excel\Facades\Excel;
use App\Exports\YourExport;

class ExportController extends Controller
{
    public function export(Request $request)
    {
        // 获取前端下拉框提交的数据(假设表单name为dropdown_items)
        $dropdownData = $request->input('dropdown_items');
        
        return Excel::download(new YourExport($dropdownData), 'report.xlsx');
    }
}

关键说明

  • 合并单元格逻辑依赖PhpSpreadsheet的Coordinate类,用于计算列的起始/结束位置
  • 通过insertNewRowBefore插入空白行,确保原有数据不被覆盖
  • 样式可根据需求调整,比如字体大小、背景色等

内容的提问来源于stack exchange,提问作者Muhd Hakimi

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.10 13:05:20