[已解决]请教关于在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;
    }
}

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

《L01 基础入门》
我们将带你从零开发一个项目并部署到线上,本课程教授 Web 开发中专业、实用的技能,如 Git 工作流、Laravel Mix 前端工作流等。
《L02 从零构建论坛系统》
以构建论坛项目 LaraBBS 为线索,展开对 Laravel 框架的全面学习。应用程序架构思路贴近 Laravel 框架的设计哲学。
讨论数量: 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 插入的是新的一行?有知道的麻烦分享一下。

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

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

3年前 评论

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

3年前 评论

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

3年前 评论

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