PHPackages                             jgrygierek/sonata-batch-entity-import-bundle - 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. jgrygierek/sonata-batch-entity-import-bundle

ActiveSymfony-bundle[PDF &amp; Document Generation](/categories/documents)

jgrygierek/sonata-batch-entity-import-bundle
============================================

Importing entities with preview and edit features for Sonata Admin.

v2.8.0(4mo ago)10951.2k↓42.5%3[1 issues](https://github.com/jgrygierek/SonataBatchEntityImportBundle/issues)MITPHPPHP &gt;=8.2.0CI failing

Since May 17Pushed 4mo ago1 watchersCompare

[ Source](https://github.com/jgrygierek/SonataBatchEntityImportBundle)[ Packagist](https://packagist.org/packages/jgrygierek/sonata-batch-entity-import-bundle)[ RSS](/packages/jgrygierek-sonata-batch-entity-import-bundle/feed)WikiDiscussions master Synced 1mo ago

READMEChangelog (10)Dependencies (20)Versions (29)Used By (0)

SonataBatchEntityImportBundle
=============================

[](#sonatabatchentityimportbundle)

[![Code Style](https://github.com/jgrygierek/SonataBatchEntityImportBundle/workflows/Code%20Style/badge.svg)](https://github.com/jgrygierek/SonataBatchEntityImportBundle/workflows/Code%20Style/badge.svg)[![Tests](https://github.com/jgrygierek/SonataBatchEntityImportBundle/workflows/Tests/badge.svg)](https://github.com/jgrygierek/SonataBatchEntityImportBundle/workflows/Tests/badge.svg)[![Code Coverage](https://camo.githubusercontent.com/39f704cecb221dac4a502d2d8f7c7f9f976c3d07126e0a3d961d3cdf92bfc982/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f6a67727967696572656b2f536f6e6174614261746368456e74697479496d706f727442756e646c652f6d6173746572)](https://camo.githubusercontent.com/39f704cecb221dac4a502d2d8f7c7f9f976c3d07126e0a3d961d3cdf92bfc982/68747470733a2f2f696d672e736869656c64732e696f2f636f6465636f762f632f6769746875622f6a67727967696572656b2f536f6e6174614261746368456e74697479496d706f727442756e646c652f6d6173746572)[![PHP Versions](https://camo.githubusercontent.com/1534d0b405b9bb0d789a6fc8b6b718b0700022832c625da411052bd8d783607e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d2533453d382e322d626c7565)](https://camo.githubusercontent.com/1534d0b405b9bb0d789a6fc8b6b718b0700022832c625da411052bd8d783607e/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f5048502d2533453d382e322d626c7565)[![Symfony Versions](https://camo.githubusercontent.com/a501bd74704379ff6a7266d17e6020802b5c817d763451f7cf16b868e0e5b08a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d352e342d2d382e2a2d626c7565)](https://camo.githubusercontent.com/a501bd74704379ff6a7266d17e6020802b5c817d763451f7cf16b868e0e5b08a/68747470733a2f2f696d672e736869656c64732e696f2f62616467652f53796d666f6e792d352e342d2d382e2a2d626c7565)[![SymfonyInsight](https://camo.githubusercontent.com/4ca35529b0decff95554eb832a260bcb88dca875a4688a17042f355d3eda6707/68747470733a2f2f696e73696768742e73796d666f6e792e636f6d2f70726f6a656374732f39623162353464332d376333322d346530352d396438392d6366623062663532313732302f6d696e692e737667)](https://insight.symfony.com/projects/9b1b54d3-7c32-4e05-9d89-cfb0bf521720)

Bundle is built on top of [BatchEntityImportBundle](https://github.com/jgrygierek/BatchEntityImportBundle).

Importing entities with preview and edit features for Sonata Admin.

- Data can be **viewed and edited** before saving to database.
- Supports **inserting** new records and **updating** existing ones.
- Supported extensions: **CSV, XLS, XLSX, ODS**.
- Supports translations from **KnpLabs Translatable** extension.
- The code is divided into smaller methods that can be easily replaced if you want to change something.
- Columns names are required and should be added as header (first row).
- If column does not have name provided, will be removed from loaded data.

[![Select File](docs/select_file.png)](docs/select_file.png)[![Edit Matrix](docs/edit_matrix.png)](docs/edit_matrix.png)

Documentation
-------------

[](#documentation)

- [Installation](#installation)
- [Configuration class](#configuration-class)
    - [Basic configuration class](#basic-configuration-class)
    - [Fields definitions](#fields-definitions)
    - [Matrix validation](#matrix-validation)
    - [Passing services to configuration class](#passing-services-to-configuration-class)
    - [Show &amp; hide entity override column](#show--hide-entity-override-column)
    - [Optimizing queries](#optimizing-queries)
- [Creating admin](#creating-admin)
- [Default Controller](#default-controller)
- [Custom Controller](#custom-controller)
- [Translations](#translations)
- [Overriding templates](#overriding-templates)
- [Importing data to array field](#importing-data-to-array-field)
- [Full example of CSV file](#full-example-of-csv-file)

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

[](#installation)

Install package via composer:

```
composer require jgrygierek/sonata-batch-entity-import-bundle

```

Add entry to `bundles.php` file:

```
JG\SonataBatchEntityImportBundle\SonataBatchEntityImportBundle::class => ['all' => true],

```

Configuration class
-------------------

[](#configuration-class)

To define how the import function should work, you need to create a configuration class.

### Basic configuration class

[](#basic-configuration-class)

In the simplest case it will contain only class of used entity.

```
namespace App\Model\ImportConfiguration;

use App\Entity\User;
use JG\BatchEntityImportBundle\Model\Configuration\AbstractImportConfiguration;

class UserImportConfiguration extends AbstractImportConfiguration
{
    public function getEntityClassName(): string
    {
        return User::class;
    }
}
```

Then register it as a service:

```
services:
  App\Model\ImportConfiguration\UserImportConfiguration: ~
```

### Fields definitions

[](#fields-definitions)

If you want to change types of rendered fields, instead of using default ones, you have to override method in your import configuration. If name of field contains spaces, you should use underscores instead.

To avoid errors during data import, you can add here validation rules.

```
use JG\BatchEntityImportBundle\Model\Form\FormFieldDefinition;
use Symfony\Component\Form\Extension\Core\Type\IntegerType;
use Symfony\Component\Form\Extension\Core\Type\TextareaType;
use Symfony\Component\Form\Extension\Core\Type\TextType;
use Symfony\Component\Validator\Constraints\Length;

public function getFieldsDefinitions(): array
{
    return [
        'age' => new FormFieldDefinition(
            IntegerType::class,
            [
                'attr' => [
                    'min' => 0,
                    'max' => 999,
                ],
            ]
        ),
        'name' => new FormFieldDefinition(TextType::class),
        'description' => new FormFieldDefinition(
            TextareaType::class,
            [
                'attr' => [
                    'rows' => 2,
                ],
                'constraints' => [new Length(['max' => 255])],
            ]
        ),
    ];
}
```

### Matrix validation

[](#matrix-validation)

This bundle provides two new validators.

1. **DatabaseEntityUnique** validator can be used to check if record data does not exist yet in database.
2. **MatrixRecordUnique** validator can be used to check duplication without checking database, just only matrix records values.

Names of fields should be the same as names of columns in your uploaded file. With one exception! If name contains spaces, you should use underscores instead.

```
use JG\BatchEntityImportBundle\Validator\Constraints\DatabaseEntityUnique;
use JG\BatchEntityImportBundle\Validator\Constraints\MatrixRecordUnique;

public function getMatrixConstraints(): array
{
    return [
        new MatrixRecordUnique(['fields' => ['field_name']]),
        new DatabaseEntityUnique(['entityClassName' => $this->getEntityClassName(), 'fields' => ['field_name']]),
    ];
}
```

### Passing services to configuration class

[](#passing-services-to-configuration-class)

If you want to pass some additional services to your configuration, just override constructor.

```
public function __construct(EntityManagerInterface $em, TestService $service)
{
    parent::__construct($em);

    $this->testService = $service;
}
```

Then you will need to define this configuration class as a public service too.

### Show &amp; hide entity override column

[](#show--hide-entity-override-column)

If you want to hide/show an entity column that allows you to override entity `default: true`, you have to override this method in your import configuration.

```
public function allowOverrideEntity(): bool
{
    return true;
}
```

### Optimizing queries

[](#optimizing-queries)

If you use **KnpLabs Translatable** extension for your entity, probably you will notice increased number of queries, because of Lazy Loading.

To optimize this, you can use `getEntityTranslationRelationName()` method to pass the relation name to the translation.

```
public function getEntityTranslationRelationName(): ?string
{
    return 'translations';
}
```

Creating admin
--------------

[](#creating-admin)

Your admin class should implement `AdminWithImportInterface` and should contain one additional method.

```
namespace App\Admin;

use App\Model\ImportConfiguration\UserImportConfiguration;
use JG\SonataBatchEntityImportBundle\Admin\AdminWithImportInterface;
use Sonata\AdminBundle\Admin\AbstractAdmin;

class UserAdmin extends AbstractAdmin implements AdminWithImportInterface
{
    public function getImportConfigurationClassName(): string
    {
        return UserImportConfiguration::class;
    }
}
```

Default controller
------------------

[](#default-controller)

If you use default controller, no action is needed. Controller will be replaced automatically.

Custom controller
-----------------

[](#custom-controller)

If you use your own custom controller, remember that this controller should:

- extend `JG\SonataBatchEntityImportBundle\Controller\ImportCrudController`
- or use `JG\SonataBatchEntityImportBundle\Controller\ImportControllerTrait`.

Additionally, if you want to automatically inject your import configuration class, remember to implement `JG\SonataBatchEntityImportBundle\Controller\ImportConfigurationAutoInjectInterface`and use method `getImportConfiguration()` from default controller.

Translations
------------

[](#translations)

This bundle supports KnpLabs Translatable behavior.

To use this feature, every column with translatable values should be suffixed with locale, for example:

- `name:en`
- `description:pl`
- `title:ru`

If suffix will be added to non-translatable entity, field will be skipped.

If suffix will be added to translatable entity, but field will not be found in translation class, field will be skipped.

Overriding templates
--------------------

[](#overriding-templates)

You have two ways to override templates globally:

- **Configuration** - just change paths to templates in your configuration file. Values in this example are default ones and will be used if nothing will be changed.

```
sonata_batch_entity_import:
    templates:
        select_file: '@SonataBatchEntityImport/select_file.html.twig'
        edit_matrix: '@SonataBatchEntityImport/edit_matrix.html.twig'
        button: '@SonataBatchEntityImport/button.html.twig'
```

- **Bundle directory** - put your templates in this directory:

```
templates/bundles/SonataBatchEntityImportBundle

```

Importing data to array field
-----------------------------

[](#importing-data-to-array-field)

If your entity has an array field, and you want to import data from CSV file to it, this is how you can do it.

- Default separator is set to `|`.
- Only one-dimensional arrays are allowed.
- Keys are not allowed.
- **IMPORTANT!** There are limitations:
    - There is no possibility to import array with one empty element, for example:
        - \[''\]
        - \[null\]
    - But arrays with at least 2 such elements are allowed:
        - \['', ''\]
        - \[null, null\]
        - \['', null\]
    - It is due of mapping CSV data to array:
        - Empty value in CSV is equal to `[]`
        - If we have default separator, `|` value in CSV is equal to `['', '']`

#### Entity

[](#entity)

- Allowed entity field types:
    - `json`
    - `array`
    - `simple_array`

```
namespace App\Entity;

use Doctrine\ORM\Mapping as ORM;

#[ORM\Entity]
class User
{
    #[ORM\Column(type: 'json']
    private array $roles = [];
}
```

#### Import configuration

[](#import-configuration)

- You have to add a field definition with a custom `ArrayTextType` type. If you skip this configuration, `TextType` will be used as default.
- You can set here your own separator.

```
use JG\BatchEntityImportBundle\Form\Type\ArrayTextType;
use JG\BatchEntityImportBundle\Model\Form\FormFieldDefinition;

public function getFieldsDefinitions(): array
{
    return [
        'roles' => new FormFieldDefinition(
            ArrayTextType::class,
            [
                'separator' => '&',
            ]
        ),
    ];
}
```

#### CSV file

[](#csv-file)

```
user_name,roles
user_1,USER&ADMIN&SUPER_ADMIN
user_2,USER
user_3,SUPER_ADMIN
```

Full example of CSV file
------------------------

[](#full-example-of-csv-file)

```
user_name,age,email,roles,country:en,name:pl
user_1,21,user_1@test.com,USER&ADMIN&SUPER_ADMIN,Poland,Polska
user_2,34,user_2@test.com,USER,England,Anglia
user_3,56,user_3@test.com,SUPER_ADMIN,Germany,Niemcy
```

###  Health Score

57

—

FairBetter than 98% of packages

Maintenance72

Regular maintenance activity

Popularity46

Moderate usage in the ecosystem

Community9

Small or concentrated contributor base

Maturity79

Established project with proven stability

 Bus Factor1

Top contributor holds 100% 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 ~75 days

Recently: every ~231 days

Total

28

Last Release

147d ago

Major Versions

v1.2.0 → v2.0.02021-09-19

v1.2.1 → v2.0.22021-11-13

v1.3.0 → v2.3.02021-11-28

v1.4.0 → v2.4.02022-04-03

v1.5.0 → v2.5.02022-12-27

PHP version history (4 changes)v1.0.0PHP ^7.4.0

v1.0.3PHP &gt;=7.4.0

v2.5.0PHP &gt;=8.1.0

v2.8.0PHP &gt;=8.2.0

### Community

Maintainers

![](https://www.gravatar.com/avatar/2d0beb45c27fa316a402deeb517b400e5dbb335564d9d1359f27cff82ff86fb3?d=identicon)[jgrygierek](/maintainers/jgrygierek)

---

Top Contributors

[![jgrygierek](https://avatars.githubusercontent.com/u/3065409?v=4)](https://github.com/jgrygierek "jgrygierek (110 commits)")

---

Tags

csv-importphpsonatasonata-adminsymfonysymfony-bundlesymfonyexcelxlsxlsxcsvodsimportentitypreviewsonata

###  Code Quality

TestsPHPUnit

Static AnalysisPHPStan, Rector

Code StylePHP CS Fixer

Type Coverage Yes

### Embed Badge

![Health badge](/badges/jgrygierek-sonata-batch-entity-import-bundle/health.svg)

```
[![Health](https://phpackages.com/badges/jgrygierek-sonata-batch-entity-import-bundle/health.svg)](https://phpackages.com/packages/jgrygierek-sonata-batch-entity-import-bundle)
```

###  Alternatives

[jgrygierek/batch-entity-import-bundle

Importing entities with preview and edit features for Symfony.

101.1M1](/packages/jgrygierek-batch-entity-import-bundle)[phpoffice/phpspreadsheet

PHPSpreadsheet - Read, Create and Write Spreadsheet documents in PHP - Spreadsheet engine

13.9k293.5M1.3k](/packages/phpoffice-phpspreadsheet)[nuovo/spreadsheet-reader

Spreadsheet reader library for Excel, OpenOffice and structured text files

669863.2k8](/packages/nuovo-spreadsheet-reader)[emiliogrv/nova-batch-load

A Laravel Nova XLS &amp; CSV importer

1641.8k](/packages/emiliogrv-nova-batch-load)[onurb/excel-bundle

Symfony Bundle to read or write Excel file (including pdf, xlsx, odt), using phpoffice/phpspreadsheet library (replacement of phpoffice/phpexcel, abandonned)

15332.0k](/packages/onurb-excel-bundle)

PHPackages © 2026

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