# Importing Data from Excel in Symfony

> Author: [Oussama Ghaieb](https://oussama.ghaieb.com/about-me)
> Canonical: https://oussama.ghaieb.com/posts/importing-data-from-excel-in-symfony

# <span class="hover:bg-yellow-100">Importing Data from Excel in Symfony</span>

Importing data from Excel files is a common requirement in Symfony applications, especially for handling bulk data entry. In this article, we'll explore how to process Excel files, validate data, and store it in a database using Symfony.

## Prerequisites

Ensure you have a Symfony project set up. If not, create one:

```sh
composer create-project symfony/skeleton my_project
cd my_project
```

Then, install the required packages:

```sh
composer require phpoffice/phpspreadsheet
```

## Creating the Import Service

We'll create a service to handle Excel file processing. First, generate a service class:

```sh
mkdir src/Service
```

Create `ExcelImporter.php`:

```php
namespace App\Service;

use PhpOffice\PhpSpreadsheet\IOFactory;
use Doctrine\ORM\EntityManagerInterface;
use App\Entity\Employee;
use App\Entity\Department;

class ExcelImporter
{
    private EntityManagerInterface $entityManager;

    public function __construct(EntityManagerInterface $entityManager)
    {
        $this->entityManager = $entityManager;
    }

    public function import(string $filePath): array
    {
        $spreadsheet = IOFactory::load($filePath);
        $sheet = $spreadsheet->getSheetByName('Employees');
        $rows = $sheet->toArray(null, true, true, true);
        
        $errors = [];
        
        foreach ($rows as $index => $row) {
            if ($index === 0) continue; // Skip header row
            
            try {
                $employee = new Employee();
                $employee->setName($row['A']);
                $employee->setPosition($row['B']);
                $employee->setDepartment($this->findDepartment($row['C']));
                $employee->setSalary((float) $row['D']);
                
                $this->entityManager->persist($employee);
            } catch (\Exception $e) {
                $errors[] = "Error at row $index: " . $e->getMessage();
            }
        }
        
        $this->entityManager->flush();
        return $errors;
    }
    
    private function findDepartment(string $name): ?Department
    {
        return $this->entityManager->getRepository(Department::class)->findOneBy(['name' => $name]);
    }
}
```

## Creating the Import Controller

Now, let's create a controller to handle file uploads.

```php
namespace App\Controller;

use App\Service\ExcelImporter;
use Symfony\Bundle\FrameworkBundle\Controller\AbstractController;
use Symfony\Component\HttpFoundation\Request;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
use Symfony\Component\HttpFoundation\File\UploadedFile;

class ImportController extends AbstractController
{
    private ExcelImporter $excelImporter;

    public function __construct(ExcelImporter $excelImporter)
    {
        $this->excelImporter = $excelImporter;
    }

    #[Route('/import', name: 'import_form', methods: ['GET'])]
    public function showForm(): Response
    {
        return $this->render('import.html.twig');
    }

    #[Route('/import', name: 'import_employees', methods: ['POST'])]
    public function import(Request $request): Response
    {
        $file = $request->files->get('excel_file');

        if (!$file instanceof UploadedFile) {
            return $this->json(['error' => 'Aucun fichier envoyé'], Response::HTTP_BAD_REQUEST);
        }

        $filePath = $file->getPathname();
        $errors = $this->excelImporter->import($filePath);

        if (!empty($errors)) {
            return $this->json(['errors' => $errors], Response::HTTP_BAD_REQUEST);
        }

        return $this->json(['message' => 'Importation réussie !'], Response::HTTP_OK);
    }
}
```

## Creating the Upload Form

Create `templates/import.html.twig`:

```twig
<!DOCTYPE html>
<html lang="en">
<head>
    <title>Import Excel</title>
</head>
<body>
    <h1>Upload Excel File</h1>
    <form action="{{ path('import_employees') }}" method="post" enctype="multipart/form-data">
        <input type="file" name="excel_file" required>
        <button type="submit">Upload</button>
    </form>
</body>
</html>
```

## Testing the Import Feature

Run your Symfony server:

```sh
symfony server:start
```

Go to `http://127.0.0.1:8000/import`, upload an Excel file, and verify that data is correctly imported into the database.

## Conclusion

Importing Excel files in Symfony is straightforward using `phpoffice/phpspreadsheet`. You can improve this by adding:

- Validation rules (e.g., ensuring required columns are not empty)
- Error logging
- Background processing for large files

Let me know if you have questions or improvements! 🚀
