Laravel-Excel 3.0 - آرایه‌های سفارشی را در قالب Excel خروجی بگیرید

ترجمه و تالیف : عرفان کاکایی
تاریخ انتشار : 13 خرداد 98
خواندن در 1 دقیقه
دسته بندی ها : لاراول

Laravel-Excel 3.0: آرایه‌های سفارشی را در قالب Excel خروجی بگیرید

اخیرا پیکج معروف Laravel-Excel نسخه 3.0 خود را منتشر کرد، که تغییراتی اساسی‌ای نسبت به نسخه قبلی‌اش داشت. من نیاز به یک خروجی اسکل ساده داشتم، و پی بردم که آموزش رسمی این پکیج فقط نحوه خروجی گرفتن از مجموعه‌های Laravel (Laravel Collections) را نشان می‌دهد و راهنمایی برای خروجی گرفتن ساختارهای سفارشی وجود ندارد؛ پس تصمیم گرفتن که خودم روش انجام آن را به شما نشان دهم.

Laravel-Excel 3.0 - آرایه‌های سفارشی را در قالب Excel خروجی بگیرید

در ابتدا، آموزش رسمی آن، اساس کار را به این صورت توضیح می‌دهد:

namespace App\Exports;
use Maatwebsite\Excel\Concerns\FromCollection;

class InvoicesExport implements FromCollection
{
    public function collection()
    {
        return Invoice::all();
    }
}

باید برای خروجی، یک کلاس مجزا بسازید (درست به مانند نحوه کا Laravel Notifications) و می‌توانید مجموعه‌ای را برای خروجی گیری تعریف کنید.

همچنین راه‌های دیگری نیز برای خروجی گرفتن داده‌ها وجود دارند.

خروجی گیری با استفاده از کوئری Eloquent:


class InvoicesExport implements FromQuery
{
    use Exportable;

    public function query()
    {
        return Invoice::query();
    }
}

یا، خروجی گیری از جدول View HTML:


class InvoicesExport implements FromView
{
    public function view(): View
    {
        return view('exports.invoices', [
            'invoices' => Invoice::all()
        ]);
    }
}

اما همچنان، مشکل این است که تمام مثال‌ها بر پایه Eloquent هستند. پس اگر یک فایل اکسل از برخی ساختارهای سفارشی مانند آرایه خواستیم چه؟

فرض کنید که این آرایه را داریم:

[
  [
    'name' => 'Povilas',
    'surname' => 'Korop',
    'email' => 'povilas@laraveldaily.com',
    'twitter' => '@povilaskorop'
  ],
  [
    'name' => 'Taylor',
    'surname' => 'Otwell',
    'email' => 'taylor@laravel.com',
    'twitter' => '@taylorotwell'
  ]
]

چگونه باید آن را در قالب اکسل خروجی بگیریم، که کلیدها ستون، و مقادیر ردیف‌ها باشند؟

دو راه برای انجام این کار وجود دارد.

گزینه ۱. آرایه خود را به یک مجموعه تبدیل کرده و به آن Heading اضافه کنید

کلاس خروجی به این شکل خواهد بود:


namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromCollection;
use Maatwebsite\Excel\Concerns\Exportable;
use Maatwebsite\Excel\Concerns\WithHeadings;

class CollectionExport implements FromCollection, WithHeadings
{
    use Exportable;

    public function collection()
    {
        return collect([
            [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => 'povilas@laraveldaily.com',
                'twitter' => '@povilaskorop'
            ],
            [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => 'taylor@laravel.com',
                'twitter' => '@taylorotwell'
            ]
        ]);
    }

    public function headings(): array
    {
        return [
            'Name',
            'Surname',
            'Email',
            'Twitter',
        ];
    }

}

باید متد collection() را با استفاده از متد collect() در Laravel، و با انتقال دادن آن به یک آرایه، پیاده‌سازی کنید. همچنین، باید متد headings() را برای اضافه کردن یک ردیف header پیاده‌سازی کنید.

در آخر، شما این ردیف را در آخر متد، و در Controller خواهید داشت:

return Excel::download(new CollectionExport(), 'export.xlsx');

سپس نیز این نتیجه دانلود شده را خواهید داشت:

Laravel-Excel 3.0 - آرایه‌های سفارشی را در قالب Excel خروجی بگیرید

گزینه ۲. آرایه را به View انتقال دهید

یک روش جایگزین نیز ساخت فایل resources/views/exports/xml.blade.php به این صورت است:

<table>
    <thead>
    <tr>
        @foreach($data[0] as $key => $value)
            <th>{{ ucfirst($key) }}</th>
        @endforeach
    </tr>
    </thead>
    <tbody>
    @foreach($data as $row)
        <tr>
        @foreach ($row as $value)
            <td>{{ $value }}</td>
        @endforeach
        </tr>
    @endforeach
    </tbody>
</table>

و سپس نیز این کد را در کلاس خروجی خود داشته باشید:


namespace App\Exports;

use Illuminate\Contracts\View\View;
use Maatwebsite\Excel\Concerns\FromView;

class BladeExport implements FromView
{

    public function view(): View
    {
        return view('exports.xml', [
            'data' => [
              [
                'name' => 'Povilas',
                'surname' => 'Korop',
                'email' => 'povilas@laraveldaily.com',
                'twitter' => '@povilaskorop'
              ],
              [
                'name' => 'Taylor',
                'surname' => 'Otwell',
                'email' => 'taylor@laravel.com',
                'twitter' => '@taylorotwell'
              ]
            ]
        ]);
    }
}

کنترلر به همان شکل باقی خواهد ماند، و فقط نام متفاوتی خواهد داشت:

return Excel::download(new BladeExport(), 'export.xlsx');

حال چگونه داده‌ها را به کلاس Excel‌ انتقال دهیم؟

هر دو مثال ما یک مشکل را دارند، و آن این است که داده‌ها در خود کلاس شکل گرفته‌اند. در واقع، این کلاس نباید چیزی درباره داده‌ها بداند، و تنها باید آن‌ها را به عنوان یک پارامتر بپذیرد. اما اگر متدهای view() یا collection() هیچ پارامتری ندارند، چگونه باید این کار را انجام دهیم؟

ما آن را از طریق متد __construct()، به داخل یک متغیر خصوصی انتقال خواهیم داد. می‌توانید این کار را «تزریق Dependency» بنامید، اما مثال‌های بسیار بهتری برای تزریق Dependency وجود دارند که می‌توانید در اینترنت ببینید.


class BladeExport implements FromView
{

    private $data;

    public function __construct($data)
    {
        $this->data = $data;
    }

    public function view(): View
    {
        return view('exports.xml', [
            'data' => $this->data
        ]);
    }
}

پس در اینجا، $data را به عنوان یک پارامتر می‌پذیریم. سپس می‌توانیم در کنترلر خود، این کد را داشته باشیم:


$data = [
    [
        'name' => 'Povilas',
        'surname' => 'Korop',
        'email' => 'povilas@laraveldaily.com',
        'twitter' => '@povilaskorop'
    ],
    [
        'name' => 'Taylor',
        'surname' => 'Otwell',
        'email' => 'taylor@laravel.com',
        'twitter' => '@taylorotwell'
    ]
];

return Excel::download(new BladeExport($data), 'export.xlsx');

امیدوارم این آموزش برای شما کاربردی بوده باشد. می‌توانید مثال‌های بیشتری را در صفحه رسمی این پکیج ببینید.

منبع

دیدگاه‌ها و پرسش‌ها

برای ارسال نظر لازم است ابتدا وارد سایت شوید
در حال دریافت نظرات از سرور، لطفا منتظر بمانید