[已解决]请教关于在Laravel-Admin中使用Laravel-Excel V3.* 导出带图片的EXCEL

  • Laravel Version: ^7.0
  • PHP Version:^7.3
  • Laravel-admin: ^1.7
  • Laravel-Excel:^3.1
<?php

namespace App\Admin\Extensions;

use Encore\Admin\Grid;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithDrawings;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\Exportable;



class StocksExporter extends ExcelExporter implements  WithDrawings,ShouldAutoSize,WithTitle,WithEvents,WithMapping
{
    use Exportable;
    protected $fileName = '采购订单.xlsx';

    protected $columns = [
        'website_id' => '店铺',
        'start_at'      => '订单日期',
        'product_title'   => '产品标题',
        'img_url' => '图片',
        'product_option' => '产品选项',
        'required_count' => '采购数量',
    ];

    public function __construct()
    {
        $this->fileName = '采购订单'.request()->start_at.'.xlsx';
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function(AfterSheet $event) {
                $event->sheet->getColumnDimension('C')->setAutoSize(false)->setWidth(10);
                $event->sheet->getColumnDimension('E')->setAutoSize(false)->setWidth(15);
            }
        ];
    }

    public function title(): string
    {
        return request()->start_at;
    }

    public function map($stock) : array
    {
        return [
            data_get($stock, 'website.url'),
            $stock->start_at->format('Y-m-d'),
            $stock->product_title.' - '.$stock->product_option,
            $stock->img_url,
            $stock->product_option,
            $stock->required_count,
        ];
    }

    public function drawings()
    {
        $i = 1;
        $result = [];
        foreach($this->getCollection() as $val) {
            $i++;
            $url = $val['img_url'];
            $file_name = basename(parse_url($url, PHP_URL_PATH));
            $arrContextOptions=array(
                "ssl"=>array(
                    "verify_peer"=>false,
                    "verify_peer_name"=>false,
                ),
            );  
            // $bool = Storage::disk('admin')->put($file_name, file_get_contents($url, false, stream_context_create($arrContextOptions)));
            ${'drawing'.$i} = new Drawing();
            ${'drawing'.$i}->setName('1111');
            ${'drawing'.$i}->setPath(public_path('uploads/'.$file_name));
            ${'drawing'.$i}->setHeight(50);
            ${'drawing'.$i}->setCoordinates('D'.$i);

            $result[] = ${'drawing'.$i}; 
        }
        return $result;
    }
}

问题描述:
导出的结果中,图片插入和数据不是同一行,如下图

《L05 电商实战》
从零开发一个电商项目,功能包括电商后台、商品 & SKU 管理、购物车、订单管理、支付宝支付、微信支付、订单退款流程、优惠券等
《L04 微信小程序从零到发布》
从小程序个人账户申请开始,带你一步步进行开发一个微信小程序,直到提交微信控制台上线发布。
讨论数量: 4
<?php

namespace App\Admin\Extensions;

use Encore\Admin\Grid;
use Encore\Admin\Grid\Exporters\ExcelExporter;
use Maatwebsite\Excel\Concerns\WithDrawings;
use PhpOffice\PhpSpreadsheet\Worksheet\Drawing;
use Illuminate\Support\Facades\Storage;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\FromArray;
use Maatwebsite\Excel\Events\AfterSheet;


class StocksExporter extends ExcelExporter implements  ShouldAutoSize,WithTitle,WithEvents,WithMapping
{
    use Exportable;
    protected $fileName = '采购订单.xlsx';

    protected $columns = [
        'website_id' => '店铺',
        'start_at'      => '订单日期',
        'product_title'   => '产品标题',
        'img_url' => '图片',
        'product_option' => '产品选项',
        'required_count' => '采购数量',
    ];

    public function __construct()
    {
        parent::__construct();
        $this->fileName = '采购订单'.request()->start_at.'.xlsx';
    }

    public function registerEvents(): array
    {
        return [
            AfterSheet::class => function(AfterSheet $event) {
                $event->sheet->getColumnDimension('D')->setAutoSize(false)->setWidth(20);

                $count = [
                    count($this->getCollection()), //column count
                ];

                for($i=0;$i<$count[0];$i++) //iterate based on row count
                {
                    $event->sheet->getRowDimension($i+2)->setRowHeight(60);
                }

                foreach($this->getCollection() as $k=>$val)
                {
                    $url = $val['img_url'];
                    $file_name = basename(parse_url($url, PHP_URL_PATH));
                    $drawing = new Drawing();
                    $drawing->setName('image');
                    $drawing->setDescription('image');
                    $drawing->setPath(public_path('uploads/'.$file_name));
                    $drawing->setHeight(70);
                    $drawing->setOffsetX(5);
                    $drawing->setOffsetY(5);
                    $drawing->setCoordinates('D'.($k+2));
                    $drawing->setWorksheet($event->sheet->getDelegate());
                }
            }
        ];
    }

    public function title(): string
    {
        return request()->start_at;
    }


    public function map($stock) : array
    {
        return [
            data_get($stock, 'website.url'),
            $stock->start_at->format('Y-m-d'),
            $stock->product_title.' - '.$stock->product_option,
            //$stock->img_url,
            '',
            $stock->product_option,
            $stock->required_count,
        ];
    }
}

用WithEvents解决了。

为什么之前用drawings 插入的是新的一行?有知道的麻烦分享一下。

4年前 评论
德国科隆街头的大胡子

多研究研究撒 我正准备搞个类似的环境试试呢结果你就解决了 :joy:

4年前 评论

@德国科隆街头的大胡子 是啊,应该多研究一下。 主要这个需求现在还被砍了,哈哈哈

4年前 评论

@ldonne 可否贴一下控制器的代码,想请教下具体怎么使用

4年前 评论

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