Une bibliothèque bien connue pour l'analyse PHP d'Excel est phpoffice/phpexcel. En utilisation réelle, lorsque vous rencontrez des dizaines de milliers de lignes Excel, l'utilisation de la mémoire de phpexcel va monter en flèche. Aujourd'hui, je vais vous présenter box/spout, une autre bibliothèque PHP qui analyse efficacement Excel.
Regardez l'introduction officielle : lisez et écrivez des fichiers de feuille de calcul de manière rapide et évolutive. On peut voir que lorsque cette bibliothèque analyse Excel, la taille du fichier Excel n'affectera pas trop l'utilisation de la mémoire. On peut dire que c'est une alternative à PHPExcel.
Depuis que le lien vers le document sur la page d'accueil Github de la bibliothèque box/spout est indisponible, voici un exemple simple de conversion d'un fichier XLSX en CSV :
include 'vendor/autoload.php'; use Box\Spout\Reader\ReaderFactory; use Box\Spout\Common\Type; $t = time(); $reader = ReaderFactory::create(Type::XLSX); //如果注释掉,单元格内的日期类型将会是DateTime,不注释的话Spout自动帮你将日期转化成string //$reader->setShouldFormatDates(true); $reader->open('./test.xlsx'); $iterator = $reader->getSheetIterator(); $iterator->rewind(); $sheet1 = $iterator->current(); $rowIter = $sheet1->getRowIterator(); foreach ($rowIter as $row) { $d = ''; foreach ($row as $col) { echo $d; if ($col instanceof DateTime) { echo $col->format('Y-m-d'); } else { echo $col; } $d = "\t"; } echo PHP_EOL; } $reader->close();
L'utilisation est toujours très simple et claire.
Comme mentionné précédemment, la taille de la mémoire consommée par la boîte/le bec lors de l'analyse n'est pas affectée par la taille du fichier Excel. Comment cela est-il réalisé ?
Voici une brève introduction : Le format de fichier XLSX est conforme à un standard appelé OOXML (https://zh.wikipedia.org/zh-cn/Office_Open_XML). XLSX est en fait un package Zip qui peut être décompressé pour voir son contenu.
Dans le tableau XLSX, si le contenu de la cellule est une chaîne, seul un stringId est enregistré lors de l'enregistrement réel, et le contenu réel de la chaîne est enregistré dans un dictionnaire de chaînes.
Lors de la lecture d'un fichier XLSX, si la cellule est une chaîne, Spout interrogera le dictionnaire String. Spout a deux méthodes de requête. L'une consiste à lire une partie du dictionnaire à partir du fichier à chaque fois et l'autre consiste à charger l'intégralité du dictionnaire en mémoire pour la requête.
Évidemment, le chargement de l'intégralité du dictionnaire String en mémoire a la vitesse de requête la plus rapide. Cependant, Spout est trop conservateur et utilise dans de nombreux cas la première méthode de requête. Modifiez donc légèrement le code de Spout et laissez Spout essayer de charger tous les dictionnaires dans la mémoire :
# Spout/Reader/XLSX/Helper/SharedStringsCaching/CachingStrategyFactory.php class CachingStrategyFactory { .... const MAX_NUM_STRINGS_PER_TEMP_FILE = 10000; // 改成50000 .... }
Essayez de convertir un EXCEL avec 1,3 w lignes, 28 colonnes et 2,8 Mo de taille en CSV pour comparaison :
方式 | 耗时 | 占用内存 |
---|---|---|
字典不加载到内存 | 185 s | 1.3 MB |
字典加载到内存 | 43 s | 9.4 MB |
Vous pouvez voir le différence de temps de traitement Encore assez importante.
Apprentissage recommandé : Tutoriel vidéo php
Ce qui précède est le contenu détaillé de. pour plus d'informations, suivez d'autres articles connexes sur le site Web de PHP en chinois!