PHPackages                             hasanhawary/export-builder - PHPackages - PHPackages  [Skip to content](#main-content)[PHPackages](/)[Directory](/)[Categories](/categories)[Trending](/trending)[Leaderboard](/leaderboard)[Changelog](/changelog)[Analyze](/analyze)[Collections](/collections)[Log in](/login)[Sign up](/register)

1. [Directory](/)
2. /
3. [PDF &amp; Document Generation](/categories/documents)
4. /
5. hasanhawary/export-builder

ActiveLibrary[PDF &amp; Document Generation](/categories/documents)

hasanhawary/export-builder
==========================

A modular Laravel export builder around maatwebsite/excel (CSV/XLS/XLSX)

v1.4.0(2mo ago)1229MITPHPPHP &gt;=8.0

Since Sep 21Pushed 2mo agoCompare

[ Source](https://github.com/hasanhawary/export-builder)[ Packagist](https://packagist.org/packages/hasanhawary/export-builder)[ Docs](https://github.com/hasanhawary/export-builder)[ RSS](/packages/hasanhawary-export-builder/feed)WikiDiscussions main Synced 1mo ago

READMEChangelogDependencies (2)Versions (7)Used By (0)

Export Builder
==============

[](#export-builder)

[![Latest Stable Version](https://camo.githubusercontent.com/bc6fd1cd84846a4ebffcdcd92576da2e61163263660bf09d5948d8f50f8e98a5/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f762f686173616e6861776172792f6578706f72742d6275696c6465722e737667)](https://packagist.org/packages/hasanhawary/export-builder)[![Total Downloads](https://camo.githubusercontent.com/1af148ad26c943fbdf56c5e701e5d6af7a8ad4c09fc7e49b13ed4ccd5546ff00/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f646d2f686173616e6861776172792f6578706f72742d6275696c6465722e737667)](https://packagist.org/packages/hasanhawary/export-builder)[![PHP Version](https://camo.githubusercontent.com/cb89b4b720744af4b7130b8314ae8aec618a975c1fd74bf000f848e25646e800/68747470733a2f2f696d672e736869656c64732e696f2f7061636b61676973742f7068702d762f686173616e6861776172792f6578706f72742d6275696c6465722e737667)](https://packagist.org/packages/hasanhawary/export-builder)[![License](https://camo.githubusercontent.com/7013272bd27ece47364536a221edb554cd69683b68a46fc0ee96881174c4214c/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f6c6963656e73652d4d49542d626c75652e737667)](LICENSE)

Lightweight, framework-friendly export generation for Laravel powered by maatwebsite/excel. Define tiny export classes and trigger CSV/XLS/XLSX downloads with built-in filtering, relations, and smart value formatting.

---

✨ Why Export Builder?
---------------------

[](#-why-export-builder)

- Zero boilerplate: focus on a simple config array, not Excel internals.
- Convention over configuration: resolves exports by page name and namespace.
- Powerful mapping: convert types (date, datetime, int, money, booleans), translate headings, and resolve enums.
- Relations aware: eager-load one/many relations, flatten nested data, count/list/concat children.
- Production-ready: safe file names, error logging, and HTTP responses that Just Work.

---

📦 Installation
--------------

[](#-installation)

```
composer require hasanhawary/export-builder
```

The package auto-discovers its service provider. Optionally publish the default configuration to config/export.php:

```
php artisan vendor:publish --tag=export-builder-config
```

Configuration option available in config/export.php:

- namespace: Default is `HasanHawary\\ExportBuilder\\Types`. Change it e.g. to `App\\Exports` to keep exports inside your app.

---

⚡ Quick Start
-------------

[](#-quick-start)

1. Create an export class under your namespace. The class name must be `{Page}Export` (StudlyCase of the `page` filter). Example: a User report export:

```
namespace App\Exports;

use HasanHawary\ExportBuilder\BaseExport;
use App\Models\User;
use App\Enum\User\UserGenderEnum;

class UserExport extends BaseExport
{
    public function __construct(array $filter)
    {
        $config = [
            'model' => User::class,
            'columns' => [
                'id' => 'int',
                'name' => 'text',
                'email' => 'text',
                'phone' => 'text',
                'gender' => UserGenderEnum::class, // enum class with static resolve($value)
                'is_active' => 'boolean',
                'last_login' => 'datetime',
                'created_at' => 'datetime',
            ],
            'relations' => [
                'one' => [
                    // foreign_key => [ relationName => [ column => type ]]
                    'created_by' => ['creator' => ['name' => 'text', 'id' => 'int']],
                ],
                'many' => [
                    'count' => [],
                    'list' => [],
                    'concat' => ['roles' => ['display_name' => 'text']]
                ],
            ],
        ];

        parent::__construct($config, $filter);
    }
}
```

2. Trigger a download from a controller/route using the Facade (recommended):

```
use HasanHawary\ExportBuilder\Facades\Export;

public function downloadUsers()
{
    $filter = [
        'page' => 'user',   // resolves to App\\Exports\\UserExport if config('export.namespace') = 'App\\\\Exports'
        'format' => 'xlsx', // csv | xlsx | xls (default: xlsx)
        // Optional
        // 'filename' => 'users_report',
        // 'timestamp' => '2025-09-21_120000',
    ];

    return (new ExportBuilder($filter))->response(); // BinaryFileResponse download
}
```

---

🔧 Configuration
---------------

[](#-configuration)

Publish the config and point the namespace to your preferred location:

```
// config/export.php
return [
    'namespace' => 'App\\Exports',
];
```

Now an incoming filter like \['page' =&gt; 'order'\] will resolve to App\\Exports\\OrderExport.

---

🧠 Columns, Types, and Formatting
--------------------------------

[](#-columns-types-and-formatting)

Declare the shape of your dataset via the columns map. BaseExport automatically converts values using the following types:

- text: raw text
- date: Y-m-d
- datetime: Y-m-d H:i:s
- array: array =&gt; "a , b , c"
- int, float, money: numeric formatting (money uses 2 decimals)
- bool/boolean: localized to api.yes/api.no
- classPath: turns a class path into its tail name and tries to translate it
- Enum classes: If a class is provided, and it has a static resolve($value) method, it will be used to map values

Headings are generated from your column keys and passed through the api.\* translation domain when available.

You can also pick specific columns at runtime by passing filter\['columns'\] = \['id','name','creator.name'\].

---

🤝 Relations (one &amp; many) and Nested Data
--------------------------------------------

[](#-relations-one--many-and-nested-data)

- one: eager-loads a single related model and flattens its fields using the pattern relation\_field.
- many: supports three useful shapes for collections:
    - count: include the total count of items
    - list: return an array of values (useful for JSON exports)
    - concat: a comma-separated string of values

You may also target nested attributes using dot notation directly in columns, e.g. 'creator.department.name' =&gt; 'text'. These are resolved automatically.

---

🔎 Filtering &amp; Query Options
-------------------------------

[](#-filtering--query-options)

You can control the dataset via the filter array you pass to your export or endpoint:

- apply\_date: boolean; when true, start/end will filter the date\_column (default created\_at)
- start, end: date boundaries (YYYY-MM-DD)
- search: full-text like filter across top-level column names
- conditions: array of \[key, operation, value\] triplets passed to where()
- order\_by, order\_dir: sorting (asc|desc)
- limit: cap the number of records (handy for previews/testing)
- type: optional segmenting helper used by BaseExport to include keys matching this string
- columns: explicit column whitelist as an array

You can change the date column by setting 'date\_column' in your export config.

---

🔐 Permissions
-------------

[](#-permissions)

Override isEnabled() in your export class to guard access with policies/permissions:

```
public function isEnabled(): bool
{
    return auth()->user()?->can('export-users');
}
```

If it returns false, the request responds with 403.

---

🧾 File Names &amp; Formats
--------------------------

[](#-file-names--formats)

- format: csv, xlsx, or xls (default xlsx)
- filename: base name; defaults to page
- timestamp: defaults to current Ymd\_His The final file name is slugified as {filename}\_{timestamp}.{ext}.

---

🛠 Troubleshooting
-----------------

[](#-troubleshooting)

- 422 Missing export page: provide filter\['page'\].
- 404 Export class not found: ensure the class name matches {Page}Export and the namespace is configured.
- 403 Forbidden: isEnabled() returned false.
- Corrupted/blank Excel: the package cleans output buffers before streaming to avoid Excel corruption issues.

---

✅ Version Support
-----------------

[](#-version-support)

- PHP: 8.0 – 8.5
- Laravel: 8 – 12

---

📚 Examples Cheat-Sheet
----------------------

[](#-examples-cheat-sheet)

- Only last 7 days and search by email:

```
['page' => 'user', 'apply_date' => true, 'start' => now()->subDays(7)->toDateString(), 'search' => '@example.com']
```

- Sort and limit:

```
['page' => 'user', 'order_by' => 'created_at', 'order_dir' => 'desc', 'limit' => 500]
```

- Add conditions (status = active):

```
['page' => 'user', 'conditions' => [ ['key' => 'status', 'operation' => '=', 'value' => 'active'] ]]
```

✅ Version Support
-----------------

[](#-version-support-1)

- **PHP**: 8.0 – 8.5
- **Laravel**: 8 – 12

---

📜 License
---------

[](#-license)

MIT © [Hasan Hawary](https://github.com/hasanhawary)

###  Health Score

40

—

FairBetter than 88% of packages

Maintenance83

Actively maintained with recent releases

Popularity15

Limited adoption so far

Community8

Small or concentrated contributor base

Maturity45

Maturing project, gaining track record

 Bus Factor1

Top contributor holds 75% of commits — single point of failure

How is this calculated?**Maintenance (25%)** — Last commit recency, latest release date, and issue-to-star ratio. Uses a 2-year decay window.

**Popularity (30%)** — Total and monthly downloads, GitHub stars, and forks. Logarithmic scaling prevents top-heavy scores.

**Community (15%)** — Contributors, dependents, forks, watchers, and maintainers. Measures real ecosystem engagement.

**Maturity (30%)** — Project age, version count, PHP version support, and release stability.

###  Release Activity

Cadence

Every ~30 days

Recently: every ~37 days

Total

6

Last Release

88d ago

### Community

Maintainers

![](https://avatars.githubusercontent.com/u/33836947?v=4)[Hassan Elhawary](/maintainers/hasanhawary)[@hasanhawary](https://github.com/hasanhawary)

---

Top Contributors

[![hassanmuhammd](https://avatars.githubusercontent.com/u/126090873?v=4)](https://github.com/hassanmuhammd "hassanmuhammd (3 commits)")[![hasanhawary](https://avatars.githubusercontent.com/u/33836947?v=4)](https://github.com/hasanhawary "hasanhawary (1 commits)")

---

Tags

laravelexportexcelxlsxlsxcsv

### Embed Badge

![Health badge](/badges/hasanhawary-export-builder/health.svg)

```
[![Health](https://phpackages.com/badges/hasanhawary-export-builder/health.svg)](https://phpackages.com/packages/hasanhawary-export-builder)
```

###  Alternatives

[maatwebsite/excel

Supercharged Excel exports and imports in Laravel

12.7k144.3M712](/packages/maatwebsite-excel)[rap2hpoutre/fast-excel

Fast Excel import/export for Laravel

2.3k24.9M47](/packages/rap2hpoutre-fast-excel)[avadim/fast-excel-laravel

Lightweight and very fast XLSX Excel Spreadsheet Export/Import for Laravel

4146.7k1](/packages/avadim-fast-excel-laravel)[emiliogrv/nova-batch-load

A Laravel Nova XLS &amp; CSV importer

1641.8k](/packages/emiliogrv-nova-batch-load)

PHPackages © 2026

[Directory](/)[Categories](/categories)[Trending](/trending)[Changelog](/changelog)[Analyze](/analyze)
