Installation
composer require akyos/ux-export
For non-Flex projects, manually enable the bundle in config/bundles.php:
Akyos\UXExportBundle\UXExportBundle::class => ['all' => true],
Mark an Entity
Annotate your entity with #[Exportable] and define properties with #[ExportableProperty]:
#[Exportable]
class User {
#[ExportableProperty(groups: ['export'])]
public string $name;
}
Integrate with Live Component
Add ComponentWithExportTrait to your Live Component and implement getData():
#[AsLiveComponent]
class UserExportComponent {
use ComponentWithExportTrait;
public string $class = User::class;
public ?string $exportGroup = 'export';
public function getData(): iterable {
return $this->userRepository->findAll();
}
}
Trigger Export Add a button in your Twig template:
<button {{ live_action('export') }}>Export</button>
Dynamic Group Selection
Use $exportGroup to switch between predefined export configurations:
public ?string $exportGroup = 'admin'; // Overrides default
Nested Data Export Extract fields from related entities:
#[ExportableProperty(groups: ['export'], fields: ['name', 'email'])]
private ?Customer $customer;
Many-to-Many Handling
Choose between row duplication (MODE_LINES) or separate sheets (MODE_SHEET):
#[ExportableProperty(groups: ['export'], manyToMany: ExportableProperty::MODE_SHEET)]
private Collection $roles;
Method-Based Export Export computed values:
#[ExportableProperty(groups: ['export'], name: 'Full Name', position: 1)]
public function getFullName(): string { ... }
CSV vs. XLSX
Toggle formats via $exportType:
public string $exportType = 'csv'; // Default is 'xlsx'
QueryBuilder or Query in getData() for efficient exports.$exportFileName for user-friendly filenames:
public string $exportFileName = 'custom_users_export';
#[Groups] as a fallback for ExportableProperty:
#[ExportableProperty(groups: ['export'])]
#[Groups(['export'])]
public string $legacyField;
Attribute Conflicts
#[ExportableProperty] groups match the $exportGroup in your component.getData() or use a default group.Circular References
fields may cause infinite loops.#[Groups] to restrict exported properties.Memory Limits
memory_limit temporarily.CSV Zip Behavior
manyToMany: MODE_SHEET is used.$exportType = 'csv' and ensure no MODE_SHEET properties exist for single-file output.Live Component State
getData().var/export/ (default path).# config/packages/dev/ux_export.yaml
ux_export:
debug: true
Serializer to test entity configuration:
$serializer->serialize($entity, 'json', ['groups' => ['export']]);
Custom Exporters
Extend ExporterService or CsvExporterService for format-specific logic:
class CustomExporter extends ExporterService {
protected function customizeWorksheet(Worksheet $sheet): void { ... }
}
Post-Export Actions
Hook into the ux_export.post_export event to modify files:
$eventDispatcher->addListener('ux_export.post_export', function (PostExportEvent $event) {
$event->getFile()->setContent(gzdeflate($event->getFile()->getContent()));
});
Dynamic Paths Override the export path per-component:
public string $exportPath = '%kernel.project_dir%/custom/exports/';
Fallback Serialization Handle unsupported types with a custom normalizer:
#[ExportableProperty(groups: ['export'])]
public DateTimeInterface $createdAt;
// In services.yaml:
Symfony\Component\Serializer\Normalizer\NormalizerInterface:
class: App\Normalizer\DateTimeNormalizer
```markdown
### Pro Tips
- **Performance**: Use DTOs for complex exports to avoid loading entire entities.
- **Localization**: Set headers dynamically:
```php
#[ExportableProperty(groups: ['export'], name: $this->translator->trans('user.name'))]
public string $name;
ExporterService in unit tests:
$this->mockBuilder(ExporterService::class)
->method('export')
->willReturn('/path/to/mock/file.xlsx');
How can I help you explore Laravel packages today?