پرش به مطلب اصلی

Export (خروجی داده‌ها)

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


فرمت‌های پشتیبانی‌شده:

  • excel
  • html
  • csv
  • xml
  • pdf

ورودی می‌تواند کلاس BaseExport، یا دادهٔ درون‌حافظه از طریق Export::data() باشد.


ایجاد کلاس Export

php artisan dornica:make-export SalesExport

برای ماژول:

php artisan dornica:make-export SalesExport --module=MODULE_NAME

ساختار پایه کلاس Export

<?php

namespace App\Exports;

use App\Models\Sale;
use Dornica\Foundation\Export\BaseExport;
use Dornica\Foundation\Export\Builders\ExportField;
use Dornica\Foundation\Export\Builders\ExportFilter;

class SalesExport extends BaseExport
{
public function __construct()
{
parent::__construct();

$this
->setTitle('Sales Report')
->setFileFormat([FileFormat::HTML, FileFormat::EXCEL])
->setModel(Sale::class);
}

public function fields(): array
{
return [
// تعریف فیلدها
];
}

public function filters(): array
{
return [
// تعریف فیلترها
];
}
}

استفاده از Blade Layout Export

در صورتی که از Blade Layout استفاده می‌کنید، می‌توانید فرم خروجی گرفتن داده‌ها را به راحتی در یک نما رندر کنید. این مورد برای پیاده‌سازی سفارشی در پروژه های پنل بسیار مفید است.

ثبت export در کنترلر
use Dornica\PanelKit\BladeLayout\Facade\BladeLayout;
use App\Exports\BookExport;

public function index()
{
BladeLayout::export(BookExport::class);

return view('books.form');
}
رندر Export در فایل Blade
<x-default-layout>

{!! bladeLayout()->export()->render() !!}

</x-default-layout>

Group By پویا در زمان اجرا

می‌توانید group-by را روی builder ست کنید (معادل BaseExport::setGroupByField).

groupByField حالا می‌تواند:

  • یک سطح
  • مبتنی بر relation با dot-notation (مثل customer.country.name)

باشد.

یک سطح (Single Level)

use App\Exports\SalesExport;
use Dornica\Foundation\Export\Builders\ExportField;
use Dornica\Foundation\Export\Facades\Export;

$result = Export::from(SalesExport::class)
->groupByField(
ExportField::make('month')
->column('paid_at')
->transform(fn ($value) => \Illuminate\Support\Carbon::parse($value)->format('Y-m'))
)
->fields(['total', 'count'])
->excel()
->generate();

relation path

$result = Export::from(SalesExport::class)
->groupByField(
ExportField::make('country')
->column('customer.country.name')
->label('Country')
)
->fields(['total', 'count'])
->excel()
->generate();

حالت‌های منبع داده (Data Driver)

  • setModel(Model::class)DataDriver::MODEL
  • setDataDriver(DataDriver::RAW) + setResource($queryOrRows)
  • setDataDriver(DataDriver::COLLECTION) + setResource(Collection)
  • setDataDriver(DataDriver::ARRAY) + setResource(array)

مثال DataDriver::MODEL

use App\Models\Sale;
use Dornica\Foundation\Export\BaseExport;
use Dornica\Foundation\Export\Builders\ExportField;

class SalesExport extends BaseExport
{
public function __construct()
{
parent::__construct();

$this->setTitle('Sales')->setModel(Sale::class);
}

public function fields(): array
{
return [
ExportField::make('id')->label('ID'),
ExportField::make('total')->label('Total'),
];
}
}

مثال DataDriver::RAW

use App\Models\Sale;
use Dornica\Foundation\Export\Enums\DataDriver;

$export = new SalesExport();
$export
->setDataDriver(DataDriver::RAW)
->setResource(
Sale::query()->where('status', 'paid')
);

$result = $export->excel()->generate();

مثال DataDriver::COLLECTION

use Dornica\Foundation\Export\Enums\DataDriver;
use Illuminate\Support\Collection;

$rows = collect([
['name' => 'Ali', 'score' => 10],
['name' => 'Sara', 'score' => 18],
]);

$export = new SalesExport();
$export
->setDataDriver(DataDriver::COLLECTION)
->setResource($rows);

$result = $export->csv()->generate();

مثال DataDriver::ARRAY

use Dornica\Foundation\Export\Enums\DataDriver;

$rows = [
['name' => 'Ali', 'score' => 10],
['name' => 'Sara', 'score' => 18],
];

$export = new SalesExport();
$export
->setDataDriver(DataDriver::ARRAY)
->setResource($rows);

$result = $export->xml()->generate();

نکته: برای سناریوهای in-memory، استفاده از Export::data($rows, $fields) معمولاً ساده‌تر است، اما در صورت نیاز به کنترل کامل، setDataDriver() + setResource() گزینهٔ مستقیم‌تری است.


استفاده از Facade Export

نقطهٔ شروع، Export::from() برای کلاس export، یا Export::data() برای ردیف‌های آماده است. انتخاب فرمت (excel(), html(), …) زنجیره را ادامه می‌دهد؛ برای ساخت فایل باید در انتها generate() یا result() صدا زده شود.

use App\Exports\SalesExport;
use Dornica\Foundation\Export\Facades\Export;

$result = Export::from(SalesExport::class)
->filters(['status' => 'paid'])
->fields(['total', 'count'])
->excel()
->generate();

if (ob_get_level()){
ob_clean();
}

return response()->download(
$result->getFilePath(),
$result->getFileName(),
['Content-Type' => $result->getMimeType()]
);

همین الگو برای html(), csv(), xml(), pdf() برقرار است.

پیش‌نمایهٔ داده بدون فایل:

$rows = Export::from(SalesExport::class)
->filters(['status' => 'paid'])
->preview();

خروجی مستقیم از داده‌ها

use Dornica\Foundation\Export\Facades\Export;

$rows = [
['name' => 'Ali', 'score' => 10],
['name' => 'Sara', 'score' => 18],
];

$fields = [
'name',
'score'
];

$result = Export::data($rows)
->fields($fields)
->csv()
->generate();

برای PDF یا XML، فقط متد فرمت را عوض کنید و ->generate() بزنید.


قالب‌های فیلتر (Filter Templates)

use App\Exports\SalesExport;
use Dornica\Foundation\Export\Facades\Export;

Export::upsertFilterTemplate(
resource: SalesExport::class,
name: 'Paid Monthly',
filters: ['status' => 'paid']
);

$result = Export::filterTemplate($templateId)
->fields(['total', 'count'])
->excel()
->generate();

نوع‌های ورودی فیلتر (Export Filters)

در Export، تمام نوع‌های متداول فیلتر و عملگرها پشتیبانی می‌شوند. علاوه بر حالت‌های قدیمی، بهتر است برای عملگرها از enum استفاده کنید:

Dornica\Foundation\Export\Enums\ExportFilterOperator

نوع‌های فیلتر

  • text
  • numeric
  • numeric_range
  • select
  • multiselect
  • radio_group
  • checkbox
  • datetime
  • daterange

نوع‌های عملگر (Operations)

Enumمقدارتوضیحنوع‌های معمول
Equalseqمساویtext, numeric, select, radio_group, checkbox
Containscontainsشاملtext
StartsWithstarts_withشروع شود باtext
EndsWithends_withپایان یابد باtext
GreaterThangtبزرگتر ازnumeric
LessThanltکوچکتر ازnumeric
Betweenbetweenبین (از/تا)numeric_range, daterange, datetime_range
Ininدر مجموعهmultiselect

نمادهای قدیمی (=, %, ^, $, >, <) هنوز پذیرفته می‌شوند و به مقادیر بالا نرمال می‌شوند.

مثال کامل تعریف filters

use Dornica\Foundation\Export\Builders\ExportFilter;
use Dornica\Foundation\Export\Enums\FilterOperator;

public function filters(): array
{
return [
ExportFilter::make('first_name')
->type('text')
->label('نام')
->operator(FilterOperator::Contains),

ExportFilter::make('id')
->type('numeric')
->label('شناسه')
->operator(FilterOperator::GreaterThan),

ExportFilter::make('id')
->type('numeric_range')
->label('بازه شناسه'),

ExportFilter::make('status')
->type('select')
->label('وضعیت')
->items([
['id' => 'paid', 'name' => 'Paid'],
['id' => 'pending', 'name' => 'Pending'],
]),

ExportFilter::make('status')
->type('multiselect')
->label('وضعیت‌ها')
->operator(FilterOperator::In)
->items([
['id' => 'paid', 'name' => 'Paid'],
['id' => 'pending', 'name' => 'Pending'],
]),

ExportFilter::make('has_special_permission')
->type('checkbox')
->label('دارای دسترسی ویژه'),

ExportFilter::make('updated_at')
->type('datetime')
->label('زمان بروزرسانی'),

ExportFilter::make('created_at')
->type('daterange')
->label('بازه تاریخ ایجاد'),

ExportFilter::make('country')
->column('customer.country.name')
->type('select')
->label('Country'),
];
}

نکات مهم

  • حداکثر تعداد ردیف خروجی در BaseExport::MAX_EXPORT_ROWS (پیش‌فرض 1000) است؛ بیشتر از این مقدار TooManyRowsException می‌دهد.
  • برای excel باید پکیج phpoffice/phpspreadsheet نصب باشد (نسخهٔ پروژه را در composer.json ببینید).
  • برای pdf باید پکیج mpdf/mpdfنصب باشد
  • برای نصب پکیج‌ها در صورت نیاز:
composer require phpoffice/phpspreadsheet
composer require mpdf/mpdf
  • همیشه برای دانلود از getFilePath() و getFileName() و getMimeType() استفاده کنید.