2015-06-16 20 views
6

Devo generare automaticamente il file Excel, il file Excel contiene da 15.000 a 50.000 righe e 75 colonne.Come generare un grande file Excel con php?

Si ottiene utilizzando un join e le formule in Excel (68 formule di Excel, ci sono IF, IFERROR, COUNTIF ...).

Quindi ho optato per la libreria PHPExcel, funziona ma devo aspettare tra 1h15 e 1h30, ho ridotto al minimo il numero di cicli. Dopo aver letto molta documentazione, ho notato che questo è il problema di PHPExcel.

Se ho pensato alla possibilità di creare un array php con tutte le formule di Excel e i dati recuperati dal mio database, un metodo che richiede molto tempo e non sono sicuro che funzionerà.

Quindi vi chiedo, c'è un altro modo? Un metodo per generare un tipo di cartella di lavoro Excel con molti dati (con 1 o 2 milioni di celle) e formule piuttosto rapidamente (entro 15 minuti).

<?php  
require_once dirname(__FILE__) . '/Classes/PHPExcel.php'; 
require_once dirname(__FILE__) . '/Classes/PHPExcel/IOFactory.php'; 

$path = "Lirefichierexcel/Trame.xlsx"; 

$objPHPExcel = new PHPExcel(); 
$sheet = $objPHPExcel-> getActiveSheet(); 

$rowCount =5; 

$worksheetTitle = $sheet->getTitle(); 
$highestRow = $sheet->getHighestRow(); // e.g. 10 
$highestColumn = $sheet->getHighestColumn(); // e.g 'F' 
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); 
$nrColumns = ord($highestColumn) - 64; 

$rowCount=5; 

    $projet=$_REQUEST['projet']; 
    try { 
     //Etablir la connexxion 
     include 'Proprietes.php'; 

     $connexion = new PDO("$driver:host=$host;dbname=$dbase", $user, $password); 

     //Préparer la requête 
     $requeteSQL="select * from $projet as a left join feuille_de_prix as b 
     on b.Liasse = a.Liasse and b.Item = a.Item order by 1"; 
     $requetePreparee= $connexion->prepare($requeteSQL); 

     //Exécuter la requête 
    $resultat = $requetePreparee->execute(); 

    //Tester le résultat 
    if(! $resultat) die("<p>La lecture a échoué</>\n"); 
    else { 

    echo "<h1>Jointure entre le $projet et la feuille de prix </h1>"; 

     while($ligne=$requetePreparee->fetch()){ 

    $sheet->SetCellValue('F'.$rowCount, $ligne[4]) 
    ->SetCellValue('F'.$rowCount, $ligne[4])  

    $rowCount++; 

    } 

     $worksheetTitle = $sheet->getTitle(); 
$highestRow = $sheet->getHighestRow(); // e.g. 10 
$highestColumn = $sheet->getHighestColumn(); // e.g 'F' 
$highestColumnIndex = PHPExcel_Cell::columnIndexFromString($highestColumn); 
$nrColumns = ord($highestColumn) - 64; 

     for ($row = 5; $row <= $highestRow; ++ $row) { 
    $row1=$row+1; 
    $rowm1=$row-1; 

     //AA4 
    $sheet->setCellValue(
      'AA' . $row, '=..............') 

//AB4 
     ->setCellValue(
      'AB' . $row,'=..............') 

} 

} 

echo date('H:i:s') , " Write to Excel2007 format" , PHP_EOL; 
$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007'); 
$objWriter->save(str_replace('.php', '.xlsx', __FILE__)); 
echo date('H:i:s') , " File written to " , str_replace('.php', '.xlsx', __FILE__) , PHP_EOL; 
// Echo memory peak usage 
echo date('H:i:s') , " Peak memory usage: " , (memory_get_peak_usage(true)/1024/1024) , " MB" , PHP_EOL; 

// Echo done 
echo date('H:i:s') , " Done writing file" , PHP_EOL; 

    $connexion=null; 

    }catch (PDOException $e) { 
    print "Erreur !: " . $e->getMessage() . "<br/>"; 
    die(); 
    } 

    ?> 
+0

Che in realtà dipende dal vostro codice, e si sta generando un grande foglio di calcolo .... PHPExcel non è veloce, ma ci sono in genere modi per codificare lo script che verrà migliorare le prestazioni generali ..... senza vedere il tuo codice, è difficile dire come; ma in base alla tua descrizione .... non creare prima array di grandi dimensioni dal tuo database e poi scrivere la matrice su PHPExcel .... scrivere su PHPExcel mentre leggi dal database e questo ti darà un grande miglioramento delle prestazioni –

+0

Grazie mille per la risposta :) Ho cercato a lungo per ridurre il tempo e non ho trovato nulla ... Inserisco il mio codice nel primo messaggio. – Krokodile

risposta

19

Utilizzare BoxSpout.

Si tratta di una libreria PHP per leggere e scrivere file CSV e XLSX, in modo veloce e scalabile. Contrariamente ad altri lettori di file o scrittori , è in grado di elaborare file di grandi dimensioni mantenendo l'utilizzo della memoria molto basso (meno di 10 MB). Ecco alcuni numeri riguardanti le prestazioni di Spout.

box spout reading and writing speeed

https://github.com/box/spout

+0

Grazie Faiz Rasool per la tua risposta: P Ho testato Spout ma non riesco a documentare bene le formule, come scrivere questa formula? $ sheet -> setCellValue ('M' $ row, '= IF (OR (CNUM (N'. $ Row. ') = 1, CNUM (N'. $ Row. ') = 2), 0,1 + CNUM (M' $ row.. '))'); – Krokodile

+0

@Krokodile perché non si fa il calcolo nel PHP e si incolla il valore nella cella? –

+0

Questa è la tecnica migliore? – Krokodile