Maatwebsite/Laravel-Excel导出视图:设置单元格自动宽度及恢复样式边框
解决Laravel-Excel导出视图时的单元格宽度自动调整与样式丢失问题
你用Maatwebsite/Laravel-Excel通过视图导出xls文件时遇到的这两个问题,都是这类场景下的常见情况,我给你整理了具体的解决方案:
一、让单元格根据内容自动调整宽度
通过view()方法导出时,Laravel-Excel不会自动帮你调整列宽,我们需要借助**WithEvents接口**,利用AfterSheet事件来实现列宽的自动适配。
修改你的导出类,实现WithEvents接口,并添加事件注册逻辑:
use Maatwebsite\Excel\Concerns\FromView; use Maatwebsite\Excel\Concerns\WithEvents; use Maatwebsite\Excel\Events\AfterSheet; use Illuminate\Contracts\View\View; class Export implements FromView, WithEvents { protected $id; public function __construct($id) { $this->id = $id; } public function view(): View { $obj = Object::find($this->id); return view('project.view', ['var' => $obj]); } // 注册事件处理逻辑 public function registerEvents(): array { return [ AfterSheet::class => function(AfterSheet $event) { // 获取工作表对象 $sheet = $event->sheet->getDelegate(); // 遍历所有列,自动调整宽度 foreach ($sheet->getColumnIterator() as $column) { // 自动计算列宽,第二个参数是最小宽度 $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true); } }, ]; } }
这段代码会在导出完成后,遍历工作表的每一列,自动根据内容调整列宽。
二、解决导出后样式和边框丢失的问题
视图导出时,HTML的样式(比如外部CSS、类选择器样式)大概率不会被Laravel-Excel解析,所以需要用以下两种方式解决:
方法1:在视图中使用内联CSS样式
Laravel-Excel对内联style属性的支持最好,直接在视图的表格标签里添加样式:
比如你的project.view视图文件:
<table style="border-collapse: collapse; width: 100%;"> <thead> <tr> <th style="border: 1px solid #000; padding: 8px; background: #f0f0f0;">标题1</th> <th style="border: 1px solid #000; padding: 8px; background: #f0f0f0;">标题2</th> </tr> </thead> <tbody> @foreach($var->items as $item) <tr> <td style="border: 1px solid #000; padding: 8px;">{{ $item->field1 }}</td> <td style="border: 1px solid #000; padding: 8px;">{{ $item->field2 }}</td> </tr> @endforeach </tbody> </table>
这种方式简单直接,适合样式不复杂的场景。
方法2:通过AfterSheet事件统一设置样式
如果不想修改视图的HTML代码,可以在导出类的AfterSheet事件中,用PhpSpreadsheet的API批量设置样式:
修改导出类的registerEvents方法:
public function registerEvents(): array { return [ AfterSheet::class => function(AfterSheet $event) { $sheet = $event->sheet->getDelegate(); $lastRow = $sheet->getHighestRow(); $lastColumn = $sheet->getHighestColumn(); // 设置整个数据区域的边框和内边距 $styleArray = [ 'borders' => [ 'allBorders' => [ 'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN, 'color' => ['argb' => '000000'], ], ], 'alignment' => [ 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER, ], 'fill' => [ 'fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['argb' => 'FFFFFF'], ], ]; // 应用样式到A1到最后一行最后一列的区域 $sheet->getStyle("A1:{$lastColumn}{$lastRow}")->applyFromArray($styleArray); // 自动调整列宽(如果需要同时实现的话) foreach ($sheet->getColumnIterator() as $column) { $sheet->getColumnDimension($column->getColumnIndex())->setAutoSize(true); } }, ]; }
这种方式适合样式统一、需要批量处理的场景,能精准控制导出文件的样式。
内容的提问来源于stack exchange,提问作者Lucentyr
相关产品推荐
相关产品推荐

