3 sencillos pasos para simplificar nuestro controlador cuando exportamos a Excel

3 sencillos pasos

Antes de comenzar permite que te pregunte algo.

¿Cómo simplificarías esto para que este separado del controlador?

Si lo piensas un momento, es posible que intentes inyectar la clase Excel en el constructor del controlador y después de eso agregues un método que contenga la lógica que crea el archivo de Excel, para obtener algo como lo siguiente.

Pero si observas por un momento te das cuenta de que esto no soluciona absolutamente ¡nada!.  A pesar de que el código parece ser más sencillo la lógica que crea el archivo sigue incrustada en el controlador.

Posiblemente este puede ser un panorama poco probable en tu vida, pero reorganizar el código para que sea más reutilizable no solo es necesario, es además una actividad muy común y estoy seguro que tarde o temprano vas a requerir reorganizar la forma en la que exportas datos a Excel.

La buena noticia es que, con solo tres pasos vas a lograr al final de este articulo un resultado como el siguiente.

¿sigues con curiosidad?, que te parece si comenzamos con el primer paso.

Paso 1: Cómo inyectar Laravel Excel  en el controlador

 

Con el ejemplo anterior te diste cuenta que inyectar la clase Excel, y agregar un nuevo método no te aporta una solución como esperabas.

¿Entonces cómo puedo resolverlo?

Es posible que no lo creas, pero la respuesta está en la documentación y para beneficio tuyo y mío; Patrick Brouwers creo algo que llama NewExcelFile Injection, que nos permite inyectar la creación de archivos de Excel en los métodos del controlador y cuenta con una clase que se llama NewExcelFile.

Déjame mostrarte que contiene esta clase.

La clase tiene varios métodos, pero el más importante en este momento es el getFilename.  Un método que tienes que implementar cuando extiendes esta clase y lo que regresa es el nombre que tendrá el archivo de Excel que vas a crear.

Dicho esto lo primero que harás, será extender la clase NewExcelFile como se muestra en el siguiente código.

Con esto ya puedes inyectar la clase UserExcelReport en lugar de la clase Excel y tendrás un archivo con el nombre de users_report listo para ser usado.

Ahora que ya tienes la clase, no queda más que decidir donde la vas a usar. En este momento de seguro estas decidiendo entre el constructor y el método, pero si aceptas mi recomendación que te parece si lo haces nuevamente en el constructor.

Así que remplaza la clase Excel por UserExcelReport como sigue.

Es posible que pienses que esto no cambia mucho de lo que hiciste anteriormente, pero…  si observas, te darás cuenta que ahora lo único que queda en el método downloadExcelReport es la lógica que requiere el archivo de Excel después de crearse.

En el siguiente paso esto lo veras de formas mas evidente.

Paso 2: Cómo separar la lógica del controlador

 

Es posible que tu mente te este diciendo en este momento: debe de haber alguna forma de mover toda esa lógica que te queda a otro lugar y dejar más despejado tu controlador.

Y eso es correcto, así que para mover la lógica que nos falta, vamos a usar un contrato que se llama ExportHandler y que ya nos proporciona Laravel Excel.

El contrato tiene un solo método llamado handle  y lo que recibe  es una instancia de UserExcelReport. En este método vas a meter toda la lógica que tienes en el controlador, así que implementa ExportHandle creando una clase UserExcelReportHandler y que debe de quedar como te muestro en el siguiente ejemplo.

Paso 3: Como realizar los últimos ajustes

 

En este punto ya removiste toda la lógica de tu controlador al Handler y estas a un paso de terminar para dormir tranquilo.

Ocupar el cambio que acabas de realizar será tan sencillo como llamar a un solo método que ya tienes disponible en la clase UserExcelReport.

Puedes ver este cambio en el siguiente ejemplo.

Sencillo ¿no lo crees?.

El método handleReport hace una llamada de forma dinámica a nuestro Handler, pero aún falta algo, la llamada a  handleReport  digamos que no es muy legible en el sentido de que no es muy expresiva así que te mostrare cómo podemos hacer el ajuste final.

Abre la clase UserExcelReport  y agrega un nuevo método;  digamos que le pones el nombre download (Lo sé, soy muy original con los nombres).

En el nuevo método solo requieres llamar a handleExport como puedes ver en el siguiente código.

Por ultimo en el controlador realiza los ajustes que te muestro.

¿Qué te parece? es seguro que más expresivo, fácil de leer y lo mejor es que lograste el objetivo de separar como se genera el Excel de tu controlador.

Conclusión

 

Para finalizar puedes realizar algunos cambios adicionales para reducir aún más la dependencia que tiene el controlador con la clase UserExcelReport inyectando en su lugar a NewExcelFile. De esta forma el controlador solo dependerá de la clase abstracta y esto puede servirte para inyectar otras implementaciones de NewExcelFiles.

Espero que te hayas divertido siguiendo este tutorial. Si tienes alguna duda, crees que no fui claro, tienes otra forma de hacer las cosas o quieres discutir el tema; por favor deja tus comentarios aquí o mándame un mensaje en el slack de Laraveles.

Por último, si te gusto este articulo y te ha servido ¡comparte!

Comparte este artículo

Entra en la discusión y deja tu comentario

  • Freddy Johanes Vargas Ramirez

    Excelente.

    • Herminio Heredia S

      Muchas gracias Freddy, espero que te sea de utilidad.

  • Muy buen tutorial, bien explicado 😉

    • Herminio Heredia S

      Gracias Jose espero que te sea util.