Para cargar datos a nuestra aplicación mientras estamos desarrollando puede que nos sea mucha utilidad el componente Seeders de Laravel que junto con los Models Factories nos permiten tener de una manera rápida y sencilla datos ficticios con los que trabajar. Pero ¿Qué sucede cuando tenemos la necesidad de cargar datos reales o dados por el mismo el mismo cliente? o éste nos solicita la funcionalidad de poder carga información en la aplicación a través de un archivo excel o csv. Para ello, veamos cómo podemos hacerlo con Laravel Excel.
Para comenzar debemos tener una instalación de Laravel con las credenciales configuradas en el archivo .env para conectarse a una base de datos.
Ahora debemos instalar el componente Laravel Excel: nos guiamos de las instrucciones dadas en Exportar hoja de cálculo con Eloquent y Laravel Excel. Al terminar, ya podemos hacer uso del componente en nuestro proyecto.
Vamos a crear un archivo CSV con el cual trabajaremos, llamado books.cvs y lo guardamos en el directorio public de nuestra aplicación, este archivo contendrá lo siguiente:
title, author, publication_year Divina Comedia,Dante Alighieri,1265 Don Quijote de la Mancha,Miguel de Cervantes,1605 Cien años de soledad,Gabriel García Márquez,1967 El viejo y el mar,Ernest Hemingway,1952 La montaña mágica,Thomas Mann,1924 1984,George Orwell,1949 Ensayo sobre la ceguera,José Saramago,1995 Clean code: A Handbook of Agile Software Craftsmanship,Robert C. Martin,2008
CSV es un tipo de archivo donde los valores están separados por comas, con los cuales se puede representar tablas, donde las columnas son los valores separados por las comas y las filas los separados por saltos de línea. Es una manera de dar formato a la información que ha sido tomado de una base de datos de manera que se puede leer y editar en software de hoja de cálculo o viceversa.
Lo siguiente es crear un modelo y su respectiva migración:
php artisan make:model -m Book
Con la opción -m estamos indicando que se cree también la migración.
Abrimos el archivo de migración creado y le agregamos los campos que tendrá la tabla:
public function up() { Schema::create('books', function (Blueprint $table) { $table->increments('id'); $table->string('name'); $table->string('author'); $table->integer('year'); $table->timestamps(); }); }
Ejecutamos la migración:
php artisan migrate
Modificamos el modelo creado para que se pueda cargar masivamente los datos, así:
<?php namespace App; use Illuminate\Database\Eloquent\Model; class Book extends Model { protected $fillable = ['name', 'author','year']; }
Ahora creamos el controlador que nos permitirá importar el archivo:
php artisan make:controller ImportController --plain
y colocamos lo siguiente:
<?php namespace App\Http\Controllers; use App\Book; use App\Http\Controllers\Controller; use Maatwebsite\Excel\Facades\Excel; class ImportController extends Controller { public function import() { Excel::load('books.csv', function($reader) { foreach ($reader->get() as $book) { Book::create([ 'name' => $book->title, 'author' =>$book->author, 'year' =>$book->publication_year ]); } }); return Book::all(); } }
El método get() o all() devuelven lo importado como una colección de filas o hojas dependiendo de la cantidad de hojas que tenga el archivo. Además, toma la primera fila como los atributos de la colección. Por tanto podemos usar los métodos para interactuar con las colecciones con el resultado de la importación.
Creamos la ruta para llamar el método en routes.php:
$router->get('import', 'ImportController@import');
Al irnos al navegador y visitamos la ruta http::laravel.app/import (esto depende de la configuración de virtual host que se tenga, sino puedes usar php artisan serve) podemos ejecutar la importación y al verificar el resultado en la base de datos:
Este es un ejemplo sencillo para cargar datos a la base de datos pero podemos hacer mucho más.
Se puede crear una clase para configurar la importación del archivo y llamarla por inyección de dependencias como se hace con los FormRequest, es decir, creamos booksImport.php en el directorio app, así:
<?php namespace App; use Maatwebsite\Excel\Files\ExcelFile; class BooksImport extends ExcelFile { public function getFile() { return public_path() . '/books.csv'; } public function getFilters() { return [ 'chunk' ]; } }
y para usar la importación con esta clase, se implementaría de esta manera en el controlador:
<?php namespace App\Http\Controllers; use App\Http\Controllers\Controller; use App\BooksImport; class ImportController extends Controller { public function import(BooksImport $import) { $import->dd(); } }
Filtro chunk
Cuando se trabaja con grandes archivos, es mejor cargarlo por lotes o chunk; para activarlo se puede usar filter(‘chunk’) y para importar por lotes se puede usar chunk($size, $callback) en vez de get(), donde el primer parámetro es el tamaño del lote y el segundo es el closure que devolverá los resultados, por ejemplo:
Excel::filter('chunk')->load(‘file.csv')->chunk(250, function($results) { foreach($results as $row) { // resultado } });
En el caso de la inyección se define el filtro en el método getFilters() y se puede usar así:
public function import(BooksImport $import) { $import->chunk(250, function($results) { // trabajar con el resultado }) }
Por otro lado se puede iterar el resultado tanto con foreach() como con each(), para este último puede ser:
// recorre las hojas $reader->each(function($sheet) { // recorre las filas $sheet->each(function($row) { }); });
En la página oficial Laravel Excel se encuentra la documentación de muchas otras características dependiendo de las necesidades. Espero te haya gustado. Recuerda dejar tus dudas en la sección de comentarios.
Material relacionado
- Exportar hoja de cálculo con Eloquent y Laravel Excel
- Model factories en Laravel 5.1
- Uso de colecciones en Laravel
Regístrate hoy en Styde y obtén acceso a todo nuestro contenido.
Lección anterior Generar PDFs en Laravel 5.1 con Snappy Lección siguiente Uso de Gravatar en Laravel 5.1