IdentifiantMot de passe
Loading...
Mot de passe oubli� ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les r�ponses en temps r�el, voter pour les messages, poser vos propres questions et recevoir la newsletter

JavaScript Discussion :

PhpSpreadsheet et d�passement de m�moire


Sujet :

JavaScript

  1. #1
    Membre �clair�
    Profil pro
    Inscrit en
    Avril 2003
    Messages
    277
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Avril 2003
    Messages : 277
    Par d�faut PhpSpreadsheet et d�passement de m�moire
    Bonjour,

    Je vous contacte parce que je suis arriv� au bout de tous les contournements que j'ai pu trouver.

    J'utilise PhpSpreadsheet pour g�n�rer des fichiers excel d'erreurs : en fonction d'un fichier en entr�e, le site effectue des contr�les et g�n�re des r�sultats de qualit� de contr�le de donn�es.
    En fonction du nombre d'enregistrements du fichier en entr�e et du nombre d'erreurs que celui-ci g�n�re, le fichier peut �tre tr�s volumineux (plus de 150 000 erreurs, donc lignes dans excel).

    Mon traitement g�n�re 13 fichiers excel. Je me rends compte qu'au fur et � mesure que le traitement avance et g�n�re les fichiers Excel, l'utilisation m�moire augmente. Je le mesure avec ce code :
    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
            $used = round(memory_get_usage(true) / 1024 / 1024, 2);
            $peak = round(memory_get_peak_usage(true) / 1024 / 1024, 2);
            $percentUsed = round(($used / ($memoryLimit / 1024 / 1024)) * 100, 2);
            $percentPeak = round(($peak / ($memoryLimit / 1024 / 1024)) * 100, 2);
            file_put_contents($logFile, "[Chunk] RAM utilisée: {$used}MB ({$percentUsed}%) | Pic: {$peak}MB ({$percentPeak}%)" . PHP_EOL, FILE_APPEND);
    Malgr� les 48 Go propos�s par l'h�bergeur, un process PHP est limit� � 2 Go.

    Voici le code pour g�n�rer un des fichiers Excel :

    Code : S�lectionner tout - Visualiser dans une fen�tre � part
    1
    2
    3
    4
    5
    6
    7
    8
    9
    10
    11
    12
    13
    14
    15
    16
    17
    18
    19
    20
    21
    22
    23
    24
    25
    26
    27
    28
    29
    30
    31
    32
    33
    34
    35
    36
    37
    38
    39
    40
    41
    42
    43
    44
    45
    46
    47
    48
    49
    50
    51
    52
    53
    54
    55
    56
    57
    58
    59
    60
    61
    62
    63
            $spreadsheet = new \PhpOffice\PhpSpreadsheet\Spreadsheet();
            $sheet = $spreadsheet->getActiveSheet();
     
            $headers = ['Code', 'Message', 'Prêt', 'Tiers', 'Collateral', 'Valeur trouvée', 'Niveau Erreur', 'Type Validation', 'Date'];
            $sheet->fromArray([$headers], NULL, 'A1');
     
            $chunkSize = 500;
            $row = 2;
     
            foreach (array_chunk($erreursDetailleesTransaction, $chunkSize) as $chunk) {
                $sheet->fromArray($chunk, NULL, "A$row");
                $row += count($chunk);
            }
     
            // Log RAM utilisée
            $used = round(memory_get_usage(true) / 1024 / 1024, 2);
            $peak = round(memory_get_peak_usage(true) / 1024 / 1024, 2);
            $percentUsed = round(($used / ($memoryLimit / 1024 / 1024)) * 100, 2);
            $percentPeak = round(($peak / ($memoryLimit / 1024 / 1024)) * 100, 2);
            file_put_contents($logFile, "[Chunk] RAM utilisée: {$used}MB ({$percentUsed}%) | Pic: {$peak}MB ({$percentPeak}%)" . PHP_EOL, FILE_APPEND);
     
            // Styles
            $headerRange = 'A1:I1';
            $dataRange = 'A2:I' . (count($erreursDetailleesTransaction) + 1);
     
            $sheet->getStyle($headerRange)->applyFromArray([
                'font' => ['bold' => true, 'color' => ['rgb' => 'FFFFFF']],
                'fill' => ['fillType' => \PhpOffice\PhpSpreadsheet\Style\Fill::FILL_SOLID, 'startColor' => ['rgb' => '4F81BD']],
                'borders' => ['allBorders' => ['borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN]],
            ]);
     
            $sheet->getStyle($dataRange)->applyFromArray([
                'borders' => ['allBorders' => ['borderStyle' => \PhpOffice\PhpSpreadsheet\Style\Border::BORDER_THIN]],
            ]);
     
            foreach (range('A', 'I') as $col) {
                $sheet->getColumnDimension($col)->setAutoSize(false);
            }
     
            $sheet->getColumnDimension('A')->setWidth(15);
            $sheet->getColumnDimension('B')->setWidth(70);
            $sheet->getColumnDimension('C')->setWidth(20);
            $sheet->getColumnDimension('D')->setWidth(20);
            $sheet->getColumnDimension('E')->setWidth(20);
            $sheet->getColumnDimension('F')->setWidth(15);
            $sheet->getColumnDimension('G')->setWidth(20);
            $sheet->getColumnDimension('H')->setWidth(70);
            $sheet->getColumnDimension('I')->setWidth(15);
     
            $sheet->getStyle($headerRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
            $sheet->getStyle($headerRange)->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
            $sheet->getStyle($dataRange)->getAlignment()->setHorizontal(\PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER);
            $sheet->getStyle($dataRange)->getAlignment()->setVertical(\PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER);
     
            $sheet->setSelectedCell('A1');
     
            $filePathTransaction .= '.xlsx';
            $writer = new \PhpOffice\PhpSpreadsheet\Writer\Xlsx($spreadsheet);
            $writer->setPreCalculateFormulas(false);
            $writer->save($filePathTransaction);
            $spreadsheet->disconnectWorksheets();
            unset($spreadsheet, $sheet, $writer, $erreursDetailleesTransaction);
            gc_collect_cycles();
    Je suis pass� par des chunks, par tout plein de contournements et il se trouve que c'est le code ci-dessus qui "r�siste" le mieux. J'obtiens une erreur invisible d�s que j'approche des 2048 Mo d'utilisation de la RAM, toujours pendant la g�n�ration d'un fichier Excel.

    Auriez-vous des id�es lumineuses pour me sortir de ce p�trin ? Ca fait des semaines que je tourne en rond. J'essaie de lib�rer la m�moire au maximum mais j'ai l'impression que �a ne change rien.
    J'en arrive � me demander si finalement, il est possible de g�n�rer un tel fichier Excel via un site web.

    J'ai bien conscience que la mise en forme prend beaucoup de ressources mais c'est vraiment un pr�requis, sinon je g�n�rerais un fichier CSV.

    La solution est peut-�tre �vidente, je d�bute, donc n'h�sitez pas � me dire si je fais n'importe quoi.

    Je vous remercie pour votre aide et reste � votre disposition pour vous apporter un maximum d'�l�ments suppl�mentaires.

  2. #2
    Expert confirm�
    Avatar de mathieu
    Profil pro
    Inscrit en
    Juin 2003
    Messages
    10 667
    D�tails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Juin 2003
    Messages : 10 667
    Par d�faut
    apr�s avoir lu les premi�res lignes de votre message, j'ai commenc� � penser au format csv. et en arrivant � la fin, je me suis rendu compte que vous n'avez pas eu besoin de moi pour penser � ce format.
    le format csv a plusieurs avantages dont celui de pouvoir �tre d�coup� en plusieurs morceaux si le contenu est trop volumineux pour l'application de d�part ou celle d'arriv�e.

    mais � part le format, il y a une autre chose � �tudier : pourquoi utiliser un tableur pour un si grand nombre de donn�es ? ces logiciels sont plut�t pr�vus pour une utilisation plus r�duite.
    en plus vous avez les donn�es d�j� accessibles dans votre code php donc �a serait beaucoup plus efficace de faire une interface web pour traiter ces donn�es. cela r�glerait les soucis d'importation et d'exportation ainsi que les probables futurs soucis de format quand les diff�rents utilisateurs n'utiliseront pas les m�mes versions du tableur.

  3. #3
    Membre �m�rite
    Homme Profil pro
    Autre
    Inscrit en
    Juillet 2021
    Messages
    433
    D�tails du profil
    Informations personnelles :
    Sexe : Homme
    Localisation : France, Loire Atlantique (Pays de la Loire)

    Informations professionnelles :
    Activit� : Autre

    Informations forums :
    Inscription : Juillet 2021
    Messages : 433
    Par d�faut
    Bonjour,

    En alternative de PhpSpreadsheet, voir OpenSpout qui est con�u pour traiter des gros fichiers en utilisant peu de m�moire.

Discussions similaires

  1. utiliser PhpSpreadsheet sans composer
    Par ouldfella dans le forum Biblioth�ques et frameworks
    R�ponses: 4
    Dernier message: 12/06/2020, 09h16
  2. R�ponses: 6
    Dernier message: 29/11/2019, 08h03
  3. [PhpSpreadSheet] Pourquoi PhpSpreadSheet retourne les deux derni�res lignes vides ?
    Par cubano2301 dans le forum Biblioth�ques et frameworks
    R�ponses: 0
    Dernier message: 31/01/2019, 13h15
  4. PhpSpreadsheet et UTF8
    Par bob456 dans le forum Biblioth�ques et frameworks
    R�ponses: 0
    Dernier message: 27/09/2018, 19h23
  5. [PhpSpreadSheet] Export Excel de donn�es
    Par tankay dans le forum Biblioth�ques et frameworks
    R�ponses: 0
    Dernier message: 18/07/2014, 14h08

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo