Importación a la base de datos de archivos Excel y CSV. Laravel 8.

Importación a la base de datos de archivos Excel y CSV. Laravel 8.
Laravel 8. Framework.

A veces necesitamos importar masivamente productos o cualquier tipo de datos a nuestra base de datos mediante archivos CSV. En este post os voy a enseñar lo simple que resulta hacerlo en Laravel 8.

Has de tener instalada la dependencia Laravel Excel ya os enseñé a hacerlo en el post Generar Archivos de Excel con Laravel 8, por lo que en este articulo, ese paso nos ahorramos, despues de tener instalada la dependencia via composer procedemos a crear los archivos necesarios para importar los archivos CSV o Excel a la Base de datos.

Utilizaremos el siguiente archivo CSV de ejemplo:

PRODUCT,CATEGORY,COST,QUANTITY
4001002,mobile,643.50€,10
1011002,car,21000.643€,1
3001002,stickers,0.05€,1000

PRODUCT,CATEGORY,COST,QUANTITY son las cabeceras como si de las columnas de la base de datos se refiere, por lo que en el script hemos de hacer que se salte la primera linea, pues no la queremos insertar en la Base de Datos, si no solo sus valores. Lo guardamos en la carpeta public de nuestra aplicación por ejemplo y lo llamamos ventas.csv.

Cramos nuesro modelo de producto con su migracion y la ejecutamos mediante php artisan migrate para actualizar nuestra base de datos con la tabla products donde despues importaremos los datos del archivo CSV. Ejecutamos en la consola el siguiente comando de artisan donde -m indiva que se cree tambien la migración.

php artisan make:model -m Product

El Modelo creado quedará de la siguiente manera:

<?php

namespace App\Models;

use Illuminate\Database\Eloquent\Factories\HasFactory;
use Illuminate\Database\Eloquent\Model;

class Product extends Model
{
    use HasFactory;

    protected $fillable = ['reference', 'category','cost', 'quantity'];

    
}

Ahora abrimos el archivo que se ha creado nuevo en la carpeta de database/migratiosn y abrimos el ultimo, pues normalmente Laravel crea los archivos de migracion ordenados por fechas. Ha de quedar de la siguiente manera y con este codigo.

<?php

use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

class CreateProductsTable extends Migration
{
    /**
     * Run the migrations.
     *
     * @return void
     */
    public function up()
    {
        Schema::create('products', function (Blueprint $table) {
            $table->id();
            $table->string('reference');
            $table->string('category');
            $table->integer('cost')->unsigned();
            $table->integer('quantity')->unsigned();
            $table->timestamps();
        });
    }

    /**
     * Reverse the migrations.
     *
     * @return void
     */
    public function down()
    {
        Schema::dropIfExists('products');
    }
}

Ejecutamos en la consola el comando php artisan migrate para crear nuestra tabla products. Despues procedemos a crear el archivo de importación con el comando de php Artisan:

php artisan make:import ProductsImport

se nos generará el archivo php en la carpeta App/imports donde colocaremos el siguiente codigo:

<?php

namespace App\Imports;

use App\Models\Product;
use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;
use Maatwebsite\Excel\Concerns\WithChunkReading;

class ProductsImport implements ToCollection, WithChunkReading
{
    /**
    * @param Collection $collection
    */
    public function collection(Collection $collection)
    {
        foreach ($collection as $row) 
        {
            if($row[0] != 'PRODUCT'){

                $ok = Product::create([
                    'reference' => $row[0],
                    'category ' => $row[1],
                    'cost'      => $row[2],
                    'quantity'  => $row[3],
                ]);

            }
        }                            
    }

    //por si fuesen archivos muy grandes
    public function chunkSize(): int
    {
        return 1000;
    }
}

Y en nuestro controlador tendremos que tener una función pública para hacer la llamada al metodo y que se desencadene la acción de importacion de los productos a la base de datos.

<?php

namespace App\Http\Controllers;


use Maatwebsite\Excel\Facades\Excel;
use App\Exports\UsersExport;
use App\Imports\ProductsImport;


class ExcelController extends Controller
{

    public function productImport() 
    {
        Excel::import(new ProductsImport, 'ventas.csv');              
    }
}

Y para finalizar, como siempre creamos nuestra ruta en el archivo web.php por ejemplo, la cargamos en nuestro navegador y listo! vamos a nuestra base de datos y a llí aparecerá nuestros productos.

Route::get('/import/products', [App\Http\Controllers\ExcelController::class, 'productImport']);