در این مثال قصد داریم یک فایل excel تولید کنیم که دارای ۱۲ برگه است. هر برگه مختص به یکی از ماههای میلادی است و در هر برگه اطلاعات کارمندان متولدین آن ماه ثبت میشود.
برای تولید فایل excel با چند برگه به دو کلاس export نیاز داریم. اولین کلاس را با دستور زیر ایجاد کنید:
$ php artisan make:exprt EmployeeExport
در این کلاس که وظیفه ی ساختن excel چند برگی را بر عهده دارد باید از اینترفیس WithMultipleSheets استفاده کنیم و متد sheets را به شکل زیر پیاده سازی کنیم:
<?php
namespace App\Exports;
use Maatwebsite\Excel\Concerns\WithMultipleSheets;
class EmployeeExport implements WithMultipleSheets
{
/**
* @return array
*/
public function sheets(): array
{
$sheets = [];
for ($month = 1;$month <= 12;$month++) {
$sheets[] = new EmployeePerMonthSheet($month);
}
return $sheets;
}
}
در متد sheets یک حلقه ۱۲ تایی ( به ازای هر ماه ) وجود دارد که به ازای هر کدام یک شی از کلاس EmployeePerMonthSheet ساخته میشود و عدد ماه به construct کلاس فرستاده میشود.
کلاس EmployeePerMonthSheet، کلاس دیگر export است که با دستور زیر آن را میسازیم:
$ php artisan make:export EmployeePerMonthSheet
این کلاس وظیفه ساخت هر برگه excel را بر عهده دارد.
قسمت جدید این کلاس شامل استفاده از اینترفیس WithTitle است که برای استفاده از آن باید متد title پیاده سازی شود و عنوان هر برگه در این متد تعیین شود.
کلاس نهایی :
<?php
namespace App\Exports;
use App\Employee;
use PhpOffice\PhpSpreadsheet\Shared\Date;
use Maatwebsite\Excel\Concerns\FromQuery;
use Maatwebsite\Excel\Concerns\ShouldAutoSize;
use Maatwebsite\Excel\Concerns\WithColumnFormatting;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Concerns\WithHeadings;
use Maatwebsite\Excel\Concerns\WithMapping;
use Maatwebsite\Excel\Concerns\WithTitle;
use Maatwebsite\Excel\Events\AfterSheet;
use PhpOffice\PhpSpreadsheet\Style\NumberFormat;
class EmployeePerMonthSheet implements FromQuery, WithTitle, WithHeadings, WithMapping, ShouldAutoSize, WithEvents, WithColumnFormatting
{
const MONTHS = [
1 => 'January',
2 => 'February',
3 => 'March',
4 => 'April',
5 => 'May',
6 => 'June',
7 => 'July',
8 => 'August',
9 => 'September',
10 => 'October',
11 => 'November',
12 => 'December',
];
protected $month;
/**
* EmployeePerMonthSheet constructor
*/
public function __construct(int $month)
{
$this->month = $month;
}
/**
* @return Builder
*/
public function query()
{
return Employee::query()
->whereMonth('birthday', $this->month);
}
/**
* @return string
*/
public function title(): string
{
return self::MONTHS[$this->month];
}
/**
* @return array
*/
public function headings(): array
{
return [
'نام', 'شغل', 'تاریخ تولد', 'نام شرکت',
'تعداد کارمندان شرکت', 'تاریخ تاسیس شرکت'
];
}
/**
* @param mixed $row
*
* @return array
*/
public function map($employee): array
{
return [
$employee->first_name . ' ' . $employee->last_name,
$employee->job,
Date::dateTimeToExcel($employee->birthday),
$employee->company->name,
$employee->company->employee_count,
Date::dateTimeToExcel($employee->company->established_at)
];
}
/**
* @return array
*/
public function columnFormats(): array
{
return [
'C' => NumberFormat::FORMAT_DATE_YYYYMMDD,
'F' => NumberFormat::FORMAT_DATE_YYYYMMDD,
];
}
/**
* @return array
*/
public function registerEvents(): array
{
$styleArray = [
'font' => [
'bold' => true
],
];
return [
AfterSheet::class =>
function (AfterSheet $event) use ($styleArray) {
$event->sheet->getStyle('A1:F1')
->applyFromArray($styleArray);
$event->sheet->setRightToLeft(true);
},
];
}
}
توضیح قسمتهای مهم
● یک property با نام month وجود دارد که مقدار عددی ماه ( ۱ تا ۱۲ ) را نگهداری میکند.
● یک const برای تبدیل عدد هر ماه به اسم آن ماه خواهیم داشت.
● در متد query با توجه به عدد ورودی فقط کارمندانی که عدد ماه تولدشان برابر با عدد ورودی باشد از دیتابیس انتخاب میشوند.
● متد title که با استفاده از const تعریف شده، عنوان هر برگه را تعیین میکند.
برای دانلود کردن این excel چند برگی هم باید یک route مانند زیر بنویسیم:
Route::get('download', function() {
return Excel::download(new EmployeeExport(), 'employees.xlsx');
});
در نهایت خروجی به صورت زیر میشود: