| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130 |
- <?php
- namespace App\Exports;
- use Illuminate\Support\Collection;
- use Maatwebsite\Excel\Concerns\FromCollection;
- use Maatwebsite\Excel\Concerns\WithCustomValueBinder;
- use Maatwebsite\Excel\Concerns\WithHeadings;
- use Maatwebsite\Excel\Concerns\WithStrictNullComparison;
- use Maatwebsite\Excel\Concerns\WithEvents;
- use Maatwebsite\Excel\Events\AfterSheet;
- use PhpOffice\PhpSpreadsheet\Cell\DefaultValueBinder;
- use PhpOffice\PhpSpreadsheet\Cell\Coordinate;
- class TableHeadExport extends DefaultValueBinder implements
- WithCustomValueBinder,
- FromCollection,
- WithStrictNullComparison,
- WithHeadings,
- WithEvents
- {
- protected $data;
- protected $headers;
- protected $headerComments; // 表头批注:键=表头名,值=批注内容
- public function __construct($data, $headers = [], $headerComments = [], $enums = [])
- {
- $this->data = $data;
- $this->headers = $headers;
- $this->headerComments = $headerComments;
- $this->enums = $enums; // 例如:['性别' => ['男', '女'], '状态' => ['启用', '禁用']]
- }
- public function collection()
- {
- return new Collection($this->createData());
- }
- public function createData()
- {
- return $this->export();
- }
- public function headings(): array
- {
- return $this->headers;
- }
- private function export()
- {
- $list = [];
- foreach ($this->data as $v) {
- $list[] = $v;
- }
- return $list;
- }
- public function registerEvents(): array
- {
- return [
- AfterSheet::class => function(AfterSheet $event) {
- if (empty($this->headerComments)) {
- return; // 不传就不加批注
- }
- $sheet = $event->sheet->getDelegate();
- // 1. 获取总列数
- $columnCount = count($this->headers);
- // 2. 循环设置每一列的宽度
- for ($i = 1; $i <= $columnCount; $i++) {
- $columnLetter = Coordinate::stringFromColumnIndex($i);
- // 设置固定宽度,例如 20
- $sheet->getColumnDimension($columnLetter)->setWidth(25);
- // 或者设置为自动宽度(根据内容自适应)
- // $sheet->getColumnDimension($columnLetter)->setAutoSize(true);
- }
- // --- 2. 核心:添加下拉枚举 (新逻辑) ---
- foreach ($this->headers as $index => $headerName) {
- if (!isset($this->enums[$headerName])) continue;
- $columnLetter = Coordinate::stringFromColumnIndex($index + 1);
- $options = $this->enums[$headerName];
- // 设置下拉范围,例如从第 2 行到第 1000 行
- $range = "{$columnLetter}2:{$columnLetter}1000";
- $validation = $sheet->getDataValidation($range);
- $validation->setType(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::TYPE_LIST);
- $validation->setErrorStyle(\PhpOffice\PhpSpreadsheet\Cell\DataValidation::STYLE_STOP);
- $validation->setAllowBlank(true);
- $validation->setShowInputMessage(true);
- $validation->setShowErrorMessage(true);
- $validation->setShowDropDown(true);
- $validation->setErrorTitle('输入错误');
- $validation->setError('请从下拉列表中选择有效选项');
- $validation->setPromptTitle('选择提示');
- $validation->setPrompt('请选择一个预设值');
- // 将数组转为 Excel 识别的格式:"项1,项2,项3"
- $validation->setFormula1('"' . implode(',', $options) . '"');
- }
- foreach ($this->headers as $index => $headerName) {
- if (!isset($this->headerComments[$headerName])) {
- continue; // 该表头没设置批注
- }
- $columnLetter = \PhpOffice\PhpSpreadsheet\Cell\Coordinate::stringFromColumnIndex($index + 1);
- $cell = $columnLetter . '1';
- $commentText = $this->headerComments[$headerName];
- // 创建批注
- $comment = $sheet->getComment($cell);
- $comment->getText()->createTextRun($commentText);
- $comment->setAuthor('系统提示');
- // 设置批注框大小(可调整数值)
- $comment->setWidth('200pt'); // 宽度
- $comment->setHeight('100pt'); // 高度
- }
- }
- ];
- }
- }
|