• laravel maatwebsite/Excel 3.1 使用教程 (导出篇)


    官方文档

    https://docs.laravel-excel.com/3.1/getting...

    GIT 地址

    https://github.com/maatwebsite/Laravel-Exc...

    作为一个和 laravel 契合度很高的 excel 工具包,大家应该都是用过这个工具。特别是 2.x 版本几乎是用 laravel 框架都接触过,3.x 基本上全部重构,全网几乎找不到比较完善的教程,我就先抛砖引玉,大概把我用到的功能使用方式列一下,欢迎大家补充。

    环境要求

    PHP: ^7.0
    Laravel: ^5.5

    安装方式
    composer require maatwebsite/excel
    

      

    因为目前 3.1 只支持 Laravel 5.5 以上,所以会自动注册。

    excel 导出

    新建导出文件,导入导出业务代码尽量不要和原来业务耦合。我们拿官网 user 模块举例

    php artisan make:export UsersExport --model=User

    会在 app 目录下创建 Exports 目录

    .
    ├── app
    │   ├── Exports
    │   │   ├── UsersExport.php
    │ 
    └── composer.json

    UsersExport.php 代码内容

    <?php
    
    namespace AppExports;
    
    use AppModelsUser;
    use MaatwebsiteExcelConcernsFromCollection;
    
    class UsersExport implements FromCollection
    {
        public function collection()
        {
            return User::all();
        }
    }

    业务控制器中调用

    use AppExportsUsersExport;
    use MaatwebsiteExcelFacadesExcel;
    use AppHttpControllersController;
    
    class UsersController extends Controller 
    {
        public function export() 
        {
            return Excel::download(new UsersExport, 'users.xlsx');
        }
    }

    很方便简单是不是。这样可以把 user 表中所有内容都导入 excel 。很显然你的业务不会如此简单,那就继续。

    Laravel Excel 支持查询语句导出、数组导出、视图表格导出,这些可以具体查看文档。

    我们通常情况下需要组装业务数据,集合导出可以作为通用的导出方案。

    <?php
    
    namespace AppExports;
    
    use AppModelsUser;
    use IlluminateSupportCollection;
    use MaatwebsiteExcelConcernsFromCollection;
    
    class UsersExport implements FromCollection
    {
        protected $data;
    
        //构造函数传值
        public function __construct($data)
        {
            $this->data = $data;
        }
        //数组转集合
        public function collection()
        {
            return new Collection($this->createData());
        }
        //业务代码
        public function createData()
        {
          //todo 业务
        }
    }

    createData 方法返回的数据格式如下

    return [
                ['编号', '姓名', '年龄']
                [1, '小明', '18岁'],
                [4, '小红', '17岁']
           ];

    需要注意的是,这里组装了 excel 的表头,这也是比较方便的地方。
    如此,简单的业务导出就完成了,应该可以满足 80% 需求,接下来我们继续,比如单元格格式化、自动适应、设置宽高、导出图片、多 sheet 表等功能。

    单元格格式化

    有时候我们需要对单元格处理文本、数字、日期、金额等格式。

    <?php
    
    namespace AppExports;
    
    use AppModelsUser;
    use MaatwebsiteExcelConcernsFromCollection;
    //新增两个 use
    use PhpOfficePhpSpreadsheetStyleNumberFormat;
    use MaatwebsiteExcelConcernsWithColumnFormatting;
    
    //新增 WithColumnFormatting
    class UsersExport implements FromCollection, WithColumnFormatting
    {
        public function collection()
        {
            return User::all();
        }
    }
    
     /**
       * @return array
       */
    public function columnFormats(): array
    {
        return [
            'B' => NumberFormat::FORMAT_DATE_DDMMYYYY, //日期
            'C' => NumberFormat::FORMAT_NUMBER_00, //金额保留两位小数
        ];
    }

    自动适应单元格宽

    <?php
    
    namespace AppExports;
    
    use AppModelsUser;
    use MaatwebsiteExcelConcernsFromCollection;
    //新增
    use MaatwebsiteExcelConcernsShouldAutoSize;
    
    //新增 ShouldAutoSize
    class UsersExport implements FromCollection, ShouldAutoSize
    {
        public function collection()
        {
            return User::all();
        }
    }

    导出多 sheet

    多表导出需要做两步操作,第一组装 sheet,第二生成对应的 sheet 表

    <?php
    
    namespace AppExports;
    
    use AppModelsUser;
    //新增
    use MaatwebsiteExcelConcernsExportable;
    use MaatwebsiteExcelConcernsWithMultipleSheets;
    
    //新增 WithMultipleSheets
    class UsersExport implements WithMultipleSheets
    {
        use Exportable;
    
        protected $year;
    
        public function __construct(int $year)
        {
            $this->year = $year;
        }
    
        /**
         * @return array
         */
        public function sheets(): array
        {
            $sheets = [];
    
            for ($month = 1; $month <= 12; $month++) {
                //不同的数据可以调用不同的方法
                $sheets[] = new UserPerMonthSheet($this->year, $month);
            }
    
            return $sheets;
        }
    }

    然后新建 UserPerMonthSheet 类

    namespace AppExports;
    
    use MaatwebsiteExcelConcernsFromQuery;
    use MaatwebsiteExcelConcernsWithTitle;
    
    class UserPerMonthSheet implements FromQuery, WithTitle
    {
        private $month;
        private $year;
    
        public function __construct(int $year, int $month)
        {
            $this->month = $month;
            $this->year  = $year;
        }
    
        /**
         * @return Builder
         */
        public function query()
        {
            return User
                ::query()
                ->whereYear('created_at', $this->year)
                ->whereMonth('created_at', $this->month);
        }
    
        /**
         * sheet 表名称
         * @return string
         */
        public function title(): string
        {
            return 'Month ' . $this->month;
        }
    }

    设置单元格高度以及垂直居中,字体颜色、背景色等

    这里需要用到 Laravel Excel 的事件模块

    提供多种事件 BeforeExport、BeforeWriting、BeforeSheet,AfterSheet 等等,也就是导出功能的生命周期,具体查看文档即可。修改单元格高度我们这里使用 AfterSheet

    namespace AppExports;
    
    use MaatwebsiteExcelConcernsWithEvents;
    use MaatwebsiteExcelEventsBeforeExport;
    use MaatwebsiteExcelEventsBeforeWriting;
    use MaatwebsiteExcelEventsBeforeSheet;
    
    class UserExport implements WithEvents
    {
        /**
         * 注册事件
         * @return array
         */
        public function registerEvents(): array
        {
            return [
                AfterSheet::class  => function(AfterSheet $event) {
                    //设置作者
                    $event->writer->setCreator('Patrick');
                    //设置列宽
                    $event->sheet->getDelegate()->getColumnDimension('A')->setWidth(50);
                    //设置行高,$i为数据行数
                    for ($i = 0; $i<=1265; $i++) {
                        $event->sheet->getDelegate()->getRowDimension($i)->setRowHeight(50);
                    }
                    //设置区域单元格垂直居中
                    $event->sheet->getDelegate()->getStyle('A1:K1265')->getAlignment()->setVertical('center');
                    //设置区域单元格字体、颜色、背景等,其他设置请查看 applyFromArray 方法,提供了注释
                    $event->sheet->getDelegate()->getStyle('A1:K6')->applyFromArray([
                        'font' => [
                            'name' => 'Arial',
                            'bold' => true,
                            'italic' => false,
                            'strikethrough' => false,
                            'color' => [
                                'rgb' => '808080'
                            ]
                        ],
                        'fill' => [
                            'fillType' => 'linear', //线性填充,类似渐变
                            'rotation' => 45, //渐变角度
                            'startColor' => [
                                'rgb' => '000000' //初始颜色
                            ],
                            //结束颜色,如果需要单一背景色,请和初始颜色保持一致
                            'endColor' => [
                                'argb' => 'FFFFFF'
                            ]
                        ]
                    ]);
                    //合并单元格
                    $event->sheet->getDelegate()->mergeCells('A1:B1');
                }
            ];
        }
    }

    我没找到能全局处理的方式,如果你们知道请告诉我,万分感谢。

    导出图片

    <?php
    
    namespace AppExports;
    
    //新增
    use MaatwebsiteExcelConcernsWithDrawings;
    use PhpOfficePhpSpreadsheetWorksheetDrawing;
    
    class UserExport implements WithDrawings
    {
        public function drawings()
        {
            $drawing = new Drawing();
            $drawing->setName('Logo');
            $drawing->setDescription('This is my logo');
            $drawing->setPath(public_path('/img/logo.jpg'));
            $drawing->setHeight(50);
            $drawing->setCoordinates('B3');
    
            $drawing2 = new Drawing();
            $drawing2->setName('Other image');
            $drawing2->setDescription('This is a second image');
            $drawing2->setPath(public_path('/img/other.jpg'));
            $drawing2->setHeight(120);
            $drawing2->setCoordinates('G2');
    
            return [$drawing, $drawing2];
        }
    }

    这是官方的例子,实际使用中我们不可能手写这么多方法块,我改写一下

    public function drawings()
    {
        //这里的数据自己组装
        $draw_arr = [1 =>'detail1.jpg', 2 => 'detail2.jpg'];
        $result = [];
        foreach ($draw_arr as $k => $v) {
          ${'drawing'.$k} = new Drawing();
          ${'drawing'.$k}->setName('Other image');
          ${'drawing'.$k}->setDescription('This is a second image');
          //图片路径
          ${'drawing'.$k}->setPath(public_path($v));
          ${'drawing'.$k}->setHeight(50);
          //设置图片列
          ${'drawing'.$k}->setCoordinates('U'.$k);
          $result[] = ${'drawing'.$k};
        }
        return $result;
    }

    maatwebsite/Excel 3.1 使用教程 (导出篇) - Laravel实战 - E度笔记
    http://www.edbiji.com/doccenter/showdoc/209/nav/3722.html

  • 相关阅读:
    django 的操作
    numpy 初步学习
    django orm 多对多操作
    selenium 安装chrome 以及chromedriver
    配置uwsgi + nginx
    ubuntu安装 anaconda
    django ---手动删除数据库
    前端(六)之盒模型显隐、定位与流式布局思想
    前端(五)之display 总结与浮动
    前端(四)之精灵图与盒模型布局
  • 原文地址:https://www.cnblogs.com/dreamboycx/p/15324368.html
Copyright © 2020-2023  润新知