:::: MENU ::::

Laravel Excel : Comment je suis passé de 600s à 12s pour exporter 25k lignes

Hi les amis,

Aujourd’hui je vais vous expliquer comment exporter de gros fichiers Excel. Durant un projet avec Laravel, ou j’ai eu à exporter des informations de la base de données en Excel, souvent ces données dépassaient les 10k.

excelbench

Au début j’ai utilisé le Wrapper le plus connu pour Laravel (https://github.com/Maatwebsite/Laravel-Excel) ce dernier utilise PHP Excel, mais rapidement j’ai remarqué que l’exportation n’était pas possible dès que le nombre de lignes dépassaient 2k…j’ai donc augmenté le temps d’exécution des scripts et la mémoire allouée (chose pas très recommandée surtout sur les petits serveurs et hébergements mutualisés) mais ça n’a rien donné car avec un temps de 600s et 128mb de mémoire allouée je n’arrivais pas à exporter plus de 10k lignes avant l’expiration du  temps accordé au script.

Après plusieurs recherches j’ai trouvé une autre librairie qui a pu optimiser l’exportation de gros fichiers Excel en utilisant le concept de stream, ce concept permet d’écrire sur le fichier et le rendre téléchargeable dès que le premier Byte est écrit, ce qui aide à réduire la mémoire utilisée et le temps d’exécution du script, cette librairie s’appelle Spout (https://github.com/box/spout).

J’ai donc essayé un Wrapper Laravel qui utilise cette librairie (https://github.com/Cyber-Duck/laravel-excel), ce Wrapper m’a permis d’exporter 25k en 100s, c’était bien mais je sentais que je pouvais faire mieux.

En continuant mes recherches j’ai trouvé l’instruction qui me faisait défaut, 85% du temps d’exécution était consommé par la conversion de la collection Eloquent vers un tableau, du coup j’ai changé l’approche utilisée, au lieu d’interroger la base de données avec Eloquent qui retourne une collection, j’ai utilisé le Query Builder qui retourne un tableau d’objets.

Seul souci le Wrapper Laravel-Excel (https://github.com/Cyber-Duck/laravel-excel) n’accepte pas un tableau mais une collection…pour ensuite faire une conversion vers un tableau, l’opération qu’il faut à tout prix éviter

J’ai fait un fork de cette librairie, j’ai ajouté le support de tableau (loadArray()) et là j’ai pu descendre à 12s pour mes 25k lignes.

Vous pouvez trouver la version modifiée sur mon Github (https://github.com/messi89/laravel-excel), cette version permet aussi de récupérer l’entête à partir des indices du tableau et aussi de créer un style a cet entête.

Ce qu’il faut retenir :

  • L’utilisation de Spout au lieu de PHPExcel.
  • L’utilisation du QueryBuilder de Laravel au lieu de l’ORM Eloquent.
  • Éviter la conversion Collection->toArray().
  • Créer le fichier Excel à partir d’un tableau.

Si vous avez des questions, des remarques, des suggestions n’hésitez à me contacter.

Voilà !!! A bientôt pour d’autres articles.


So, what do you think ?