|
@@ -0,0 +1,130 @@
|
|
|
|
|
+<?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'); // 高度
|
|
|
|
|
+ }
|
|
|
|
|
+ }
|
|
|
|
|
+ ];
|
|
|
|
|
+ }
|
|
|
|
|
+}
|