Dans cet article, j'explique ma méthodologie lorsque j'ai besoin d'importer un grand nombre de produit depuis un fichier excel vers un site e-commerce.
Bien que l'exemple utilise des produits, il est également possible de l'utiliser pour importer tout type de données, que ce soit des utilisateurs, des produits, des articles de blog etc...
Dernier point : j'utilise dans le cadre de cet article le framework Symfony. Bien que cela oriente légérement le code, il est tout à fait possible d'utiliser un autre framework, ou simplement PHP "pure".
Pour importer nos produits, nous allons utiliser la librairie PHPOffice / PhpSpreadsheet.
Commençont par l'installer en utilisant Composer :
composer require phpoffice/phpspreadsheet
Si vous n'avez pas composer installé, vous pouvez l'installer ici, ou installer la librairie manuellement depuis leur GitHub
Tous d'abord, il est nécessaire d'instancier un
Reader
: c'est la classe qui permet la lecture du fichier. Il existe plusieurs readers, adapté à chaque version de fichier (.csv, .xlsx...). Dans mon cas, ce sera
Xlsx
, mais cela n'as pas d'impact sur la suite, car ils fonctionnent tous de la même manière.
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx()
La première étape pour importer les données sera de charger le fichier. Pour cela, nous utiliserons l'instruction suivante :
$spreadSheet = $reader->load($file);
Ensuite, il faudra sélectionner la feuille à utiliser. Si votre fichier n'en contient qu'une, vous pouvez utiliser l'instruction suivante :
$sheet = $spreadSheet->getActiveSheet();
Sinon, vous pouvez utiliser la méthode suivante pour sélectionner une feuille en fonction de son nom :
$sheet = $spreadSheet->getSheetByName("nom-de-ma-feuille");
Nous utiliserons ensuite la méthode $sheet->getCell("identifiant_cellule")
pour sélectionner une cellule, puis la méthode GetValue()
nous permettra de récupérer sa valeur.
Maintenant que vous avez accès au fichier, il va falloir boucler dessus pour en lire les données.
Avant tout, il est nécessaire de déterminer comment procéder : il faut alors analyser le fichier que vous aller utiliser pour choisir la bonne méthode d'import.
Selon le cas, il faudra agir différement. Si votre fichier n'est pas "nettoyé", vous avez deux options : nettoyer le fichier au préalable manuellement, ce qui peut être très long dépendant de la taille du fichier. Vous pouvez également prendre en compte dans votre code que certaines valeurs ne sont pas correct : ignorer les valeurs nulles, ou les lignes incomplètes
Pour cet exemple, nous utiliserons la structure suivante pour le fichier excel, et considererons qu'il est déja "propre".
Nom du produit | Description | Prix |
---|---|---|
Table basse | Table basse en bois d'acajou. Dimensions 150cm x 70cm | 145 |
Luminaire | Luminaire sur pieds. Dimensions 185cm x 45cm | 89 |
Chaise de jardin | Chaise de jardin en plastique | 24 |
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadSheet = $reader->load($file);
$sheet = $spreadSheet->getActiveSheet();
// Permet d'itérer sur les lignes du fichier
$rows = $sheet->getRowIterator();
// Récupère l'EntityManager (remplacer par PDO si vous n'utilisez pas Doctrine)
$em = $doctrine->getManager();
$i = 0;
foreach($rows as $row) {
// On ignore la première ligne car elle contient les titres. Si vous n'avez pas les titres dans votre fichier, vous pouvez ignorer cette ligne.
if ($i === 0) {
$i++;
continue;
}
$product = new Product();
// Le nom du produit se situe sur la première colonne du fichier
$product->setName($sheet->getCell("A1")->getValue());
$product->setDescription($sheet->getCell("B1")->getValue());
// Il est nécessaire de cast la valeur car un string est retourné
$product->setPrice((int) $sheet->getCell("C1")->getValue());
// Enregistre la requête (remplacer par PDO si vous n'utilisez pas Doctrine)
$em->persist($product);
}
// Envoie les requêtes à la base de données (remplacer par PDO si vous n'utilisez pas Doctrine)
$em->flush();
Pour cet exemple, imaginons un fichier incomplet.
Nom du produit | Description | Prix |
---|---|---|
Table basse | 145 | |
Luminaire | Luminaire sur pieds. Dimensions 185cm x 45cm | |
Chaise de jardin | Chaise de jardin en plastique | 24 |
$reader = new \PhpOffice\PhpSpreadsheet\Reader\Xlsx();
$spreadSheet = $reader->load($file);
$sheet = $spreadSheet->getActiveSheet();
// Permet d'itérer sur les lignes du fichier
$rows = $sheet->getRowIterator();
// Récupère l'EntityManager (remplacer par PDO si vous n'utilisez pas Doctrine)
$em = $doctrine->getManager();
$i = 0;
foreach($rows as $row) {
// On ignore la première ligne car elle contient les titres. Si vous n'avez pas les titres dans votre fichier, vous pouvez ignorer cette ligne.
if ($i === 0) {
$i++;
continue;
}
$product = new Product();
// Si pas de nom de produit ou de prix, on ignore la ligne
if ($sheet->getCell("A$i)->getValue() == null || $sheet->getCell("C$i)->getValue()) {
continue;
}
// Le nom du produit se situe sur la première colonne du fichier
$product->setName($sheet->getCell("A1")->getValue());
// On accepte qu'il n'y ait pas de description, mais on la remplace par le titre si elle n'existe pas
$product->setDescription($sheet->getCell("B1")->getValue() ? $sheet->getCell("B1")->getValue() : $sheet->getCell("A1")->getValue());
// Il est nécessaire de cast la valeur car un string est retourné
$product->setPrice((int) $sheet->getCell("C1")->getValue());
// Enregistre la requête (remplacer par PDO si vous n'utilisez pas Doctrine)
$em->persist($product);
}
// Envoie les requêtes à la base de données (remplacer par PDO si vous n'utilisez pas Doctrine)
$em->flush();
Et voilà, c'est déja finit ! Si vous avez des questions, n'hésitez pas à me contacter par email: contact@paul-le-flem.fr