PHPackages                             real-media-technic-staudacher/laravel-flatfiles - 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. [Framework](/categories/framework)
4. /
5. real-media-technic-staudacher/laravel-flatfiles

ActiveProject[Framework](/categories/framework)

real-media-technic-staudacher/laravel-flatfiles
===============================================

Export and import flatfiles with Laravel like charm

v5.0.6(1mo ago)276.7k↓34.5%MITPHPPHP &gt;=8.0CI failing

Since Dec 7Pushed 1mo ago2 watchersCompare

[ Source](https://github.com/real-media-technic-staudacher/laravel-flatfiles)[ Packagist](https://packagist.org/packages/real-media-technic-staudacher/laravel-flatfiles)[ RSS](/packages/real-media-technic-staudacher-laravel-flatfiles/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (8)Versions (27)Used By (0)

Export Eloquent queries to flatfiles using simple configuration
===============================================================

[](#export-eloquent-queries-to-flatfiles-using-simple-configuration)

![](https://camo.githubusercontent.com/a84a075b5454a0aaf5935d18a18586d1a944bd59f359f98a012c2dc55270554a/68747470733a2f2f696d672e736869656c64732e696f2f6769746875622f6973737565732d7261772f7265616c2d6d656469612d746563686e69632d737461756461636865722f6c61726176656c2d666c617466696c65732f736869656c64732e737667)[![TravisCI](https://camo.githubusercontent.com/9fe3b04f1b2a290b36c41173083f33f75ca63f68bf007c984cb5f783be5d4b3b/68747470733a2f2f696d672e736869656c64732e696f2f7472617669732f7265616c2d6d656469612d746563686e69632d737461756461636865722f6c61726176656c2d666c617466696c65732e737667)](https://travis-ci.org/real-media-technic-staudacher/laravel-flatfiles)

Installation
------------

[](#installation)

```
composer require real-media-technic-staudacher/laravel-flatfiles:^5.0

```

To overwrite the default configuration

```
php artisan vendor:publish

```

Then select the option `Provider: RealMediaTechnicStaudacher\LaravelFlatfiles\FlatfileExportServiceProvider`. The default configuration looks like:

```
return [
    'default' => env('FLATFILE_DRIVER', 'csv'),

    'drivers' => [
        'csv' => [
            'charset'               => 'UTF-8',
            'delimiter'             => ';',
            'enclosure'             => '"',
            'bom'                   => true,
            'force_enclosure'       => false,
            'ignore_sylk_exception' => false,
        ],
    ],
];
```

As you see, right now, only CSV exports are supported ;-)

Usage example / Basic workflow
------------------------------

[](#usage-example--basic-workflow)

```
// Implement FlatfileFields to define your export fields (See later sections for details)
class ExportJob implements ShouldQueue, FlatfileFields
{
    // FlatfileExporter magically find out, whether your auto-injecting method's class implement the FlatfileFields-interface!
    // If so, it use this field definition by default
    public function handle(FlatfileExport $flatfile, $exportFilepath = '/subfolderOnDisk/export.csv')
    {
        // Expose where to export the file. Based on file extension (ie. .csv) we select the proper exporter for you)
        $flatfile->to($exportFilepath, 'diskNameOrInstance');

        $flatfile->addHeader();

        // You may want to load any data globally to prevent database queries for each row or even cell
        $imagePaths = $this->imagepaths();

        // Only needed for very custom contents in your flatfile!
        $flatfile->beforeEachRow(function (Model $model) use ($imagePaths) {
            // Do some very special magic to make custom image paths available for your "cells" for
            // each row.
            // Typically here you merge the globally loaded objects with the data you need for you cell
            // $model here is an eloquent model selected by queryToSelectEachRow()
        });

        // Here we use a query builder (if you want to) and ensure to restrict memory usage by chunking
        $this->queryToSelectEachRow()->chunk(500, function ($chunk) use ($flatfile) {
            $flatfile->addRows($chunk);
        });

        // Dont forget to properly "close" the operation by this command
        $flatfile->moveToTarget();
    }

    // In your field definition to are supposed to "only" pick out loaded or prepared data instead of
    // doing complex calculations (See beforeEachRow())
    public function fields(): array {
        return []; // Your field definition
    }

    // Return an elequent query builder and carefully eager load relations you will gonna use in your cells!
    protected function queryToSelectEachRow() {
        return Products::whereCategory(15)->with('images');
    }
}
```

Load export
-----------

[](#load-export)

Easiest way is to auto-inject the `FlatfileExport` while implementing the `FlatfileFields` interface:

```
// This will lookup for your field definition in the current class
class ExportJob implements ShouldQueue, FlatfileFields
{
    public function handle(FlatfileExport $flatfile) {}
}
```

If you want to use a dedicated class for field definitions are get the array from somewhere else use `withFields()`

```
    public function handle(FlatfileExport $flatfile) {
        $flatfile->withFields($objImplementingFlatfileFields);

        // Alternatively you can resolve and assign fields in one step
        // app(FlatfileExport::class, [$objImplementingFlatfileFields]);
        // app(FlatfileExport::class, ['fields' => $objImplementingFlatfileFields]);
    }
```

Specify target file / location
------------------------------

[](#specify-target-file--location)

### Using filesystem disk

[](#using-filesystem-disk)

- This enables you to export to all available filesystem drivers
- Exports are generated locally/temporary first and than streamed to disk

```
    $flatfile->to('relative/path/to/file-with-extension.csv', Storage::disk('name'));

    // Do export ...

    $flatfile->moveToTarget();
```

Prepare global export resources
-------------------------------

[](#prepare-global-export-resources)

...

Loop through data and write to export file
------------------------------------------

[](#loop-through-data-and-write-to-export-file)

- Preselect the models that will represent a single row in your flat file
- Chunk through this result set to limit resources

```
    public function handle()
    {
        $flatfile = app(FlatfileExport::class, [$this]);
        $flatfile->to($this->csvFilepath, $this->disk);

        // Optionally add a Header
        $flatfile->addHeader();

        // Proposed way to step through a large result set
        $this->queryToSelectEachRow()->chunk(500, function ($chunk) use ($flatfile) {
            $flatfile->addRows($chunk);
        });
    }

    protected function queryToSelectEachRow(): Builder
    {
        return CampaignModels::whereCampaignId($this->campaignId)->with(['model.product', 'campaign']);
    }
```

Finish export
-------------

[](#finish-export)

```
$flatfile->moveToTarget();

```

Define fields
-------------

[](#define-fields)

Fields are defined within an object/class implementing the `FlatfileFields` interface, thus a `public function field()`. Implement this function directly in your export-handling class, or in a dedicated sort like a DTO class.

Why? You get the possiblity to add callbacks in your field definitions, so that you can define dynamic cells easily

In your `field()` method you need to define an array of fields. This will generate a flatfile with one column each field array element.

Assume we load a collection of products having attributes named `product_name`. The definition looks like:

```
    $fields = [
        'product_name' => 'Product Name'
    ];
```

The field defintions are pretty flexible. Better learn by examples by yourself

```
    $fields = [
        'relation.columnOfRelation' => 'Column Header Label', // Relations should be eager loaded
        [
            'label'    => 'Label with special characters',
            'column'   => 'relation.columnOfRelation', // Value of param $value in callback (optional)
            'callback' => function ($model, $value) { // Format cell values
                return $model->currencySign.' '.number_format($value);
            }
        ],
        'attribute' => [ // Column name can also still be the key of the array
            'label'    => 'Label with special characters',
            'callback' => function ($model, $value) {}
        ],
        'Column header' => function() { // For callbacks the header label can also be specified in the key! Crazy...
            return 'static cell content';
        },
        'Empty cell' => '',
    ];
```

One row for each relation
-------------------------

[](#one-row-for-each-relation)

If you have a relation you want to put into one row and preserve it's parent as one row if it hasn't a relation, you can use the following:

```
    public function handle()
    {
        // ...

        // relation has to be loaded in items of course
        $items->each(function (Item $item) use ($export) {
          $export->addRowForEachRelation($item, ['relation', 'more.*.relations'], 'fieldAccessorAlias', true);
        });

        // ...
    }

    public function fields(): array
    {
        return [
            'fieldAccessorAlias.fieldName' => 'Output of relation fieldName if it is existing',
            'fieldAccessorAlias.fieldNameMoreRelations' => 'Output of more.*.relations fieldName if it is existing',
        ];
    }
```

SYLK file format error
----------------------

[](#sylk-file-format-error)

By default, an exception getting thrown if the first column in the header row is named `ID`. Background for this is the SYLK formatting, which does not allow an flawless opening with Microsoft Excel in some Versions. You are free to disable the exception via the config `drivers.csv.ignore_sylk_exception` again.

Upgrade guide
-------------

[](#upgrade-guide)

### To v3 from v2

[](#to-v3-from-v2)

- Added return types. Also in interfaces. So mainly interfaces have to be checked: ie. `public function fields(): array;`. Tipp: Search for `public function fields(` across the whole project.
- New Namespace. Change imports from `LaravelFlatfiles\*` to `RealMediaTechnicStaudacher\LaravelFlatfiles\*`
- Changed order of callback paramters of field callback method to prevent `$null` in most of the calls `function ($null, Asset $asset)`. Now: `function (Asset $asset)`. Tipp: Search for `function ($null` and all `function fields` in your editor.

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance89

Actively maintained with recent releases

Popularity32

Limited adoption so far

Community12

Small or concentrated contributor base

Maturity78

Established project with proven stability

 Bus Factor1

Top contributor holds 90.9% 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 ~126 days

Recently: every ~294 days

Total

25

Last Release

56d ago

Major Versions

v0.4.2 → v1.0.02020-02-03

v1.1 → v2.02020-03-25

v2.0.1 → v3.02020-06-03

v3.1 → v4.02020-09-14

v4.1.1 → v5.02022-12-31

PHP version history (4 changes)0.1.0PHP &gt;=7.0.0

v0.4PHP &gt;=7.1

v4.0PHP &gt;=7.3

v5.0PHP &gt;=8.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/76590d8c18de5295f46fe50d2b33eaec56878553dd7ca8aff93a3a6f648cd31b?d=identicon)[patriziotomato](/maintainers/patriziotomato)

---

Top Contributors

[![patriziotomato](https://avatars.githubusercontent.com/u/544502?v=4)](https://github.com/patriziotomato "patriziotomato (80 commits)")[![quaddy](https://avatars.githubusercontent.com/u/8025038?v=4)](https://github.com/quaddy "quaddy (5 commits)")[![zappzerapp](https://avatars.githubusercontent.com/u/9962724?v=4)](https://github.com/zappzerapp "zappzerapp (2 commits)")[![Tschucki](https://avatars.githubusercontent.com/u/43211841?v=4)](https://github.com/Tschucki "Tschucki (1 commits)")

---

Tags

frameworklaravelexportimportosflatfilescoop

###  Code Quality

TestsPHPUnit

### Embed Badge

![Health badge](/badges/real-media-technic-staudacher-laravel-flatfiles/health.svg)

```
[![Health](https://phpackages.com/badges/real-media-technic-staudacher-laravel-flatfiles/health.svg)](https://phpackages.com/packages/real-media-technic-staudacher-laravel-flatfiles)
```

###  Alternatives

[codewithdennis/larament

Larament is a time-saving starter kit to quickly launch Laravel 13.x projects. It includes FilamentPHP 5.x pre-installed and configured, along with additional tools and features to streamline your development workflow.

3691.5k](/packages/codewithdennis-larament)[kompo/kompo

Laravel &amp; Vue.js FullStack Components for Rapid Application Development

11812.4k21](/packages/kompo-kompo)

PHPackages © 2026

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