您现在的位置是: 网站首页> PHP> Laravel Laravel

Laravel 框架使用 Maatwebsite\Excel 包导出Excel文件,下拉列表的数据来源过长问题

Smile 2024-09-07 21:36:54 PHP Laravel 阅读:894

简介当Excel文件下拉列表数据源长度超过255个字符时,下拉列表就会显示异常。解决方法是将数据源列表放入其他空置的单元格中,并通过公式引用这些单元格,或者是将数据源列表放置于新建的Sheet工作表中的单元格中,然后通过设置数据验证公式引用这些新建Sheet工作表中的单元格。这样可以确保即使数据源较长,下拉列表也能正常显示。

1、在 Laravel中 使用 maatwebsite/excel 包导出Excel文件,首先需要安装这个包:

composer require maatwebsite/excel

2、添加测试路由:

Route::get('test/export', [TestController::class, 'export']);

3、运行 make:controller 命令快速创建控制器类:

php artisan make:controller TestController

在 TestController 控制器中调用 TestExport 导出类,代码如下:

<?php

namespace App\Http\Controllers;

use App\Exports\TestExport;
use Maatwebsite\Excel\Facades\Excel;

class TestController extends Controller 
{
    public function export() 
    {
        $data =  collect([
            ['姓名', '年龄', '性别', '爱好'],
            ['张三', '18', '男', '读书'],
            ['李四', '20', '女', '游泳']
        ]);

        $drop = [
            'dropColumn' => ['C', 'D'],
            'dropData' => [
                ['男', '女', '未知'],
                ['读书', '游泳', '打篮球'],
            ],
        ];

        $title = '员工花名册';

        $export = new TestExport($data, $title, $drop);

        return Excel::download($export, 'test.xlsx');
    }
}

4、运行 make:export 命令快速创建导出类:

php artisan make:export TestExport

新建的文件位于 app/Exports 目录下,修改文件,代码如下:

<?php

namespace App\Exports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\WithColumnWidths;
use Maatwebsite\Excel\Concerns\WithStyles;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use PhpOffice\PhpSpreadsheet\Cell\DataValidation;
use PhpOffice\PhpSpreadsheet\Worksheet\Worksheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;

class TestExport implements FromCollection, WithTitle, WithColumnWidths, WithStyles, WithColumnFormatting
{
    private $data; //导出数据
    private $drop; //单元格下拉单元格和数据源
    private $title; //表格Sheet名称

    public function __construct(Collection $data, string $title, array $drop = [])
    {
        $this->data = $data;
        $this->drop = $drop;
        $this->title = $title;
    }

    /**
     * 设置表格Sheet名称
     * @return string
     */
    public function title(): string
    {
        return $this->title;
    }

    /**
     * 设置单元格列宽
     * @return array
     */
    public function columnWidths(): array
    {
        return [
            'A' => 18,
            'B' => 18,
            'C' => 18,
            'D' => 18,
        ];
    }

    /**
     * 设置单元格格式
     * @return array
     */
    public function columnFormats(): array
    {
        return [
            'A:D' => NumberFormat::FORMAT_TEXT, // 设置A-D列的值类型为字符串
            // 如果需要设置更多列,在此处添加,例如:'B' => NumberFormat::FORMAT_TEXT
        ];
    }

    /**
     * 表格数据填充
     * @return \Illuminate\Support\Collection
     */
    public function collection(): Collection
    {
        return $this->data;
    }

    /**
     * 设置单元格样式
     */
    public function styles(Worksheet $sheet)
    {
        $dropColumn = $this->drop['dropColumn'] ?? [];
        $dropData = $this->drop['dropData'] ?? [];
        foreach ($dropColumn as $key => $value) {
            $strLen = strlen(implode(',', $dropData[$key]));
            if ($strLen >= 255) {
                // 创建一个新的 sheet 用于存放下拉列表的数据源
                $dropDownListSheet = $sheet->getParent()->createSheet();
                $dropDownListSheet->setTitle($value . '_dropData'); //此处使用中划线- 导出的表格有异常,需注意

                // 填充数据到新的 sheet 中
                $dropDataFirstElement = $dropData[$key];
                foreach ($dropDataFirstElement as $index => $dataItem) {
                    $column = 'A' . ($index + 1); // 使用 A 列存储数据
                    $dropDownListSheet->setCellValue($column, $dataItem);
                }
            }
        }

        //生成下拉列表框
        foreach ($this->data as $key => $value) {
            if ($key == 0 || empty($dropColumn))
                continue;

            foreach ($dropColumn as $k => $v) {
                $dropCell = $v . ($key + 1); //从第2行开始
                $objActSheet = $sheet;
                $objValidation1 = $sheet->getCell($dropCell)->getDataValidation();
                $objValidation1 = $objActSheet->getCell($dropCell)->getDataValidation();
                $objValidation1->setType( DataValidation::TYPE_LIST)
                    ->setErrorStyle(DataValidation::STYLE_INFORMATION)
                    ->setAllowBlank(false)
                    ->setShowInputMessage(true)
                    ->setShowErrorMessage(true)
                    ->setShowDropDown(true)
                    ->setErrorTitle('输入的值有误')
                    ->setError('您输入的值不在下拉框列表内')
                    ->setPromptTitle('下拉选择框')
                    ->setPrompt('请从下拉框中选择您需要的值');

                $strLen = strlen(implode(',', $dropData[$k]));
                if ($strLen >= 255) {
                    $objValidation1->setFormula1($v . '_dropData!$A$1:$A$' . count($dropData[$k]));
                } else {
                    $objValidation1->setFormula1('"' . implode(',', $dropData[$k]) . '"');
                }
            }
        }
    }
}

5、如果你更喜欢使用普通数组而不是集合,则可以使用 FromArray:

<?php
namespace App\Exports;

use App\Invoice;
use Maatwebsite\Excel\Concerns\FromArray;

class TestExport implements FromArray
{
    public function array(): array
    {
        return [
            [1, 2, 3],
            [4, 5, 6]
        ];
    }
}

6、最终效果如下:

很赞哦! (0)

文章评论

站点信息