De PHPExcel à PhpSpreadsheet (Migration pour Laravel)

Ceux qui utilisent PHPExcel l’auront remarqué, cela fait déjà un moment que composer nous demande de migrer de l’un vers l’autre. Est-ce vraiment indispensable ? Comment migrer son code ? Quel intêret de basculer vers PHPSpreadsheet. Je vous propose ici un petit tour d’horizon de ce qui change.

Qu’elles sont les avantages / incovénients ?

Dans les avantages de PHPSpreadhseet, la première des choses, c’est d’avoir un code qui est maintenu. PHPExcel, lui a été abandonné. On peut noter aussi que des espaces de nom ont étés ajoutés. Cela complexifie un peu l’utilisation, mais ca permet de mieux isoler les classes. Les colonnes commencent désormais à 1 et non 0 (c’est plus logique vis à vis d’excel). Certaines fonctions devront être appelés différemment, mais grosso modo, l’outil fait la même chose (on verra ca plus loin).

Dans les inconvénients, on peut noter qu’une simple mise à jour de composer ne suffit pas. Vous devrez réécrire chaque endroit de votre code où vous génériez un fichier Excel. Suivant votre projet, cela peut vous prendre pas mal de temps.

Composer et dépendances

Avoir des packages dépréciés, c’est un peu casse gueule à la longue, et il vaut mieux prendre le temps de s’adapter avant d’arriver au pied du mur et de devoir revoir tout son code . Voyons ensemble comment y arriver.

La première chose à faire, c’est donc de modifier son composer.json :
Avant vous aviez ça:
« phpoffice/phpexcel »: « ^1.8 »,
maintenant vous devez avoir ça:
« phpoffice/phpspreadsheet »: « ^1.4 »,

puis de lancer une mise à jour avec composer update (vous auriez aussi pu faire un
composer require phpoffice/phpspreadsheet).

Laravel devrait avoir besoin d’un fichier config\excel.php qui va remplacer l’existant. Pour cela, il faut faire un :
php artisan vendor:publish –provider=Maatwebsite\Excel\ExcelServiceProvider

Pour information, les informations du fichier app.php ne changent pas, et la documentation pour Laravel se trouve ici: https://github.com/Maatwebsite/Laravel-Excel

Comment télécharger un fichier:

Avant on se reposait sur la façade Excel, on créait notre fichier, et on lui passant les lignes dans des variables globales. La variable sheet nous permettant d’intervenir directement sur la feuille, et de lui mettre des valeurs, et des styles, ainsi que plein d’autres fonctions qu’on peut retrouver dans PHPExcel (mais ça, c’était avant).

Excel::create('Export-'.date("Y-m-d"), function($excel) {
	global $tabRowsColors;
	global $export_type;
	global $tabDates;
	global $sDateFin;
			
	$mysheet = $excel->sheet('Export', function($sheet) {
		global $rows;				
		foreach ($rows as $row){
		     $sheet->row($iRow, $row);
      		     $iRow++;
		}				
	});
})->export('xlsx');
			

Aujourd’hui, cela ne fonctionne plus comme ça !

Plusieurs fonctions ont étés dépréciées à commencer par create. Désormais, il vous faudra utiliser download qui marche plus ou moins pareil.
Excel::download($oReport, ‘Export-‘.date(« Y-m-d »).’.xlsx’);

Seulement voilà, vous perdez la notion de feuille, et donc vous perdez vos accès aux styles, et autres modifications. Il y a certainement plusieurs façons de faire, mais je vais vous proposer la mienne qui répond à 95% des besoins (je pense).

Pensez objets et méthodes:

J’ai créér les 2 objets suivants ReportExcel et ReportExcelSheet.
Le 1er représente le classeur, et le 2e une feuille. Je vais donc avoir le code suivant:

$report = new ReportExcel();
$sheet = new ReportExcelSheet('Synthèse');
$sheet->setData($rows);
$report->addSheet($sheet);
return Excel::download($report, 'Export-'.date("Y-m-d").'.xlsx');	

Ce que l’ont faisait avant en remplissant des lignes, doit se faire aujourd’hui en remplissant des collections, et la modification des styles doit se faire via des évènements. L’objet feuille doit donc implémenter un certain nombre d’interfaçe:
WithTitle, FromCollection, WithHeadings, ShouldAutoSize, WithEvents
(il y en a peut être d’autres qu’il faudrait rajouter, mais pour mon besoin, je n’en ai pas besoin).
Ensuite, je rajoute des méthodes pour remplir mes attributs (headers, data, styles, et title)

Modification des styles:

De nombreuses fonctions ont étés supprimées, ou modifiées. Vous trouverez la liste ici, ainsi qu’un outil de migration.
Personnellement, j’utilisais beaucoup getCellByColumnAndRow pour séléctionner une cellule(et bien attention car désormais il faut ajouter 1 à la variable colonne).
Et j’utilisais aussi beaucoup applyFromArray (maintenant l’argument type de fill doit se renommer en fillType).
Pour définir les styles, il faut donc désormais passer par les méthodes d’événements. Dans mon exemple, je peux rajouter un certain nombre de styles en précisant la colonne et la ligne, ainsi que le style à appliquer. Et mon code reste quasi identique entre PHP Excel et PHP Spreadsheet.

AfterSheet::class => function(AfterSheet $event) {
   foreach ($this->styles as $style){
	$event->sheet->getDelegate()->getCellByColumnAndRow($style["column"],$style["row"])->getStyle()->applyFromArray($style["style"]);
	}
 },

Vous trouverez mes fichiers en pièce jointe. Vous verrez que j’utilise aussi des constructeurs pour simplifier la tâche, ainsi il est possible de ne pas passer par l’objet feuille si notre classeur ne concerne qu’une seule feuille. J’envisage peut-être d’en faire un package, je ne sais pas trop encore… D’ici là, bonnes modifications.
Si vous avez des points de blocage comme nombre d’entre vous sur stackoverflow, n’hésitez pas à demander, les commentaires sont là pour ça.

Laisser un commentaire

Ce site utilise Akismet pour réduire les indésirables. En savoir plus sur comment les données de vos commentaires sont utilisées.