maatwebsite/excel使用:导出——扩展

扩展

事件

导出过程有几个事件,您可以利用这些事件与底层类进行交互,为导出添加自定义行为。

您可以通过使用事件来挂钩父包,而无需使用诸如 “query” 或 “view” 之类的便捷方法,如果您需要对导出进行全面控制。

事件将通过添加 WithEvents 来激活。在 registerEvents 方法中,您需要返回一个事件数组。键是事件的完全限定名称(FQN),值是一个可调用的事件监听器。这可以是一个闭包、数组调用或可调用类。

namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeExport;
use Maatwebsite\Excel\Events\BeforeWriting;
use Maatwebsite\Excel\Events\BeforeSheet;

class InvoicesExport implements WithEvents
{
    /**
     * @return array
     */
    public function registerEvents(): array
    {
        return [
            // 使用闭包处理。
            BeforeExport::class => function(BeforeExport $event) {
                $event->writer->getProperties()->setCreator('Patrick');
            },

            // 数组调用,引用静态方法。
            BeforeWriting::class => [self::class, 'beforeWriting'],

            // 使用具有 __invoke 方法的类。
            BeforeSheet::class => new BeforeSheetHandler()
        ];
    }

    public static function beforeWriting(BeforeWriting $event) 
    {
        //
    }
}

请注意,使用 Closure 无法与导出队列结合使用,因为 PHP 无法序列化闭包。在这种情况下,最好使用 RegistersEventListeners 特性。

自动注册事件监听器

通过使用 RegistersEventListeners 特性,您可以自动注册事件监听器,而无需使用 registerEvents 方法。只有当方法被创建时,监听器才会被注册。

namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;
use Maatwebsite\Excel\Events\BeforeExport;
use Maatwebsite\Excel\Events\BeforeWriting;
use Maatwebsite\Excel\Events\BeforeSheet;
use Maatwebsite\Excel\Events\AfterSheet;

class InvoicesExport implements WithEvents
{
    use Exportable, RegistersEventListeners;

    public static function beforeExport(BeforeExport $event)
    {
        //
    }

    public static function beforeWriting(BeforeWriting $event)
    {
        //
    }

    public static function beforeSheet(BeforeSheet $event)
    {
        //
    }

    public static function afterSheet(AfterSheet $event)
    {
        //
    }
}

全局事件监听器

如果希望在应用程序的所有导出中执行相同的操作,也可以全局配置事件监听器。您可以将它们添加到 AppServiceProviderregister() 方法中。

Writer::listen(BeforeExport::class, function () {
    //
});

Writer::listen(BeforeWriting::class, function () {
    //
});

Sheet::listen(BeforeSheet::class, function () {
    //
});

Sheet::listen(AfterSheet::class, function () {
    //
});

可用事件

事件名称 负载 解释
Maatwebsite\Excel\Events\BeforeExport $event->writer : Writer 事件在过程开始时触发。
Maatwebsite\Excel\Events\BeforeWriting $event->writer : Writer 事件在下载/存储开始前触发。
Maatwebsite\Excel\Events\BeforeSheet $event->sheet : Sheet 事件在工作表创建后立即触发。
Maatwebsite\Excel\Events\AfterSheet $event->sheet : Sheet 事件在工作表过程结束时触发。

自定义关注点 (Concerns)

您可以在应用程序中添加自定义关注点。这对于在几个项目之间共享某些关注点或开源您的自定义关注点非常有用。

让我们在应用程序中添加一个 WithCustomProperties 关注点。您可以将这些关注点添加到 App/Exports/Concerns,但只要 Composer 可以自动加载,任何位置都可以。

namespace App\Exports\Concerns;

interface WithCustomProperties
{
    /**
     *
     * @return string
     */
    public function description(): string;
}

除了这个关注点,我们还将创建一个关注点处理器 WithCustomPropertiesHandler。这个类也可以添加到 App/Exports/Concerns,但完全取决于您的选择。关注点处理器基本上是一个可调用的类。它接收您的导出对象以及一个 WriterSheet 对象,具体取决于选择的事件。

namespace App\Exports\Concerns;

use App\Exports\Concerns\WithCustomProperties;
use Maatwebsite\Excel\Writer;

class WithCustomPropertiesHandler
{
    /**
     * @param WithCustomProperties $exportable
     * @param Writer               $writer
     */
    public function __invoke(WithCustomProperties $exportable, Writer $writer)
    {
        $writer
            ->getDelegate()
            ->getProperties()
            ->setDescription(
                $exportable->description()
            );
    }
}

然后我们在服务提供者中注册这个关注点。您可以使用 App/Providers/AppServiceProvider 来完成这一操作。

public function register()
{
    Excel::extend(WithCustomProperties::class, new WithCustomPropertiesHandler);
}

💡 ::extend 接受一个可调用的参数作为第二个参数。您也可以传递一个闭包。

public function register()
{
    Excel::extend(WithCustomProperties::class, function(WithCustomProperties $exportable, Writer $writer) {
        $writer->getDelegate()->getProperties()->setDescription($exportable->description());
    });
}

您还可以将关注点处理器绑定到不同的挂钩。默认情况下,关注点处理器总是绑定到 BeforeWriting 事件。您可以通过提供第三个参数轻松自定义这一点。

public function register()
{
    Excel::extend(WithCustomProperties::class, new WithCustomPropertiesHandler, BeforeExport::class);
}

宏扩展

WriterSheet 都是“宏扩展”的,这意味着它们可以轻松扩展以满足您的需求。WriterSheet 都有一个 ->getDelegate() 方法,该方法返回底层的 PhpSpreadsheet 类。这将允许您添加自定义宏作为 PhpSpreadsheet 方法的快捷方式,这些方法在本包中不可用。

Writer

use \Maatwebsite\Excel\Writer;

Writer::macro('setCreator', function (Writer $writer, string $creator) {
    $writer->getDelegate()->getProperties()->setCreator($creator);
});

Sheet

use \Maatwebsite\Excel\Sheet;

Sheet::macro('setOrientation', function (Sheet $sheet, $orientation) {
    $sheet->getDelegate()->getPageSetup()->setOrientation($orientation);
});

自定义

您可以创建自己的宏来为电子表格实例添加自定义方法。

例如,为了给单元格添加样式,我们首先创建一个宏,命名为 styleCells

use \Maatwebsite\Excel\Sheet;

Sheet::macro('styleCells', function (Sheet $sheet, string $cellRange, array $style) {
    $sheet->getDelegate()->getStyle($cellRange)->applyFromArray($style);
});

一旦宏创建完成,就可以在 registerEvents() 方法中使用它,如下所示:

namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\BeforeExport;
use Maatwebsite\Excel\Events\AfterSheet;

class InvoicesExport implements WithEvents
{
    /**
     * @return array
     */
    public function registerEvents(): array
    {
        return [
            BeforeExport::class  => function(BeforeExport $event) {
                $event->writer->setCreator('Patrick');
            },
            AfterSheet::class    => function(AfterSheet $event) {
                $event->sheet->setOrientation(\PhpOffice\PhpSpreadsheet\Worksheet\PageSetup::ORIENTATION_LANDSCAPE);

                $event->sheet->styleCells(
                    'B2:G8',
                    [
                        'borders' => [
                            'outline' => [
                                'borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THICK,
                                'color' => ['argb' => 'FFFF0000'],
                            ],
                        ]
                    ]
                );
            },
        ];
    }
}

RTL(从右到左)工作表

要更改 Excel 工作表的方向,可以使用 setRightToLeft(true),如以下示例所示:

namespace App\Exports;

use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;

class InvoicesExport implements WithEvents
{
    /**
     * @return array
     */
    public function registerEvents(): array
    {
        return [
            AfterSheet::class    => function(AfterSheet $event) {
                $event->sheet->getDelegate()->setRightToLeft(true);
            },
        ];
    }
}

请随意使用上述宏,或者发挥创意,发明您自己的宏!

有关 PhpSpreadsheet 方法,请参阅 他们的文档

本作品采用《CC 协议》,转载必须注明作者和本文链接
《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 4

快进到 使用 xlswriter-docs.viest.me/ maatwebsite/excel 这个太卡了,2k行数据就爆炸了

1个月前 评论
看上隔壁小花了啦 1个月前
newcomer 1个月前

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!