2015-06-16 15 views
6

Muszę wygenerować automatycznie plik Excel, plik Excel zawiera od 15 000 do 50 000 wierszy i 75 kolumn.Jak wygenerować duży plik Excela za pomocą php?

Uzyskuje się za pomocą sprzężenia i formuł w programie Excel (68 formuł programu Excel, są IF, IFERROR, COUNTIF ...).

Więc zdecydowałem się na bibliotekę PHPExcel, działa, ale muszę czekać od 1h15 do 1h30, zminimalizowałem liczbę pętli. Po przeczytaniu dużej dokumentacji zauważyłem, że jest to problem PHPExcel.

Jeśli pomyślałem o możliwości utworzenia tablicy php ze wszystkimi formułami Excela i danymi pobranymi z mojej bazy danych, metoda ta zajmuje dużo czasu i nie jestem pewna, czy zadziała.

Więc pytam cię, czy istnieje inny sposób? Metoda generowania typu skoroszytu programu Excel z dużą ilością danych (z 1 lub 2 milionami komórek) i formułami raczej szybko (w ciągu 15 minut).

<?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

To naprawdę zależy od kodu, a generują duży arkusz .... PHPExcel nie jest szybki, ale istnieją sposoby na ogół do kodu skryptu, który będzie popraw ogólną wydajność ... bez wyświetlania kodu, trudno powiedzieć jak; ale na podstawie twojego opisu .... nie buduj najpierw dużych tablic z bazy danych, a następnie napisz tablicę do PHPExcel .... napisz do PHPExcel podczas czytania z bazy danych, co da ci dużą poprawę wydajności –

+0

Dziękuję bardzo za odpowiedź :) Szukałem długo, aby zminimalizować czas i nic nie znalazłem ... Wpisuję mój kod do pierwszej wiadomości. – Krokodile

Odpowiedz

19

Użyj BoxSpout.

Jest to biblioteka PHP do odczytu i zapisu CSV i XLSX plików, w sposób szybki i skalowalny sposób. W przeciwieństwie do innych czytników plików lub pisarzy , jest w stanie przetwarzać bardzo duże pliki przy zachowaniu bardzo niskiego zużycia pamięci (mniej niż 10 MB). Oto kilka liczb dotyczących wydajności Spout.

box spout reading and writing speeed

https://github.com/box/spout

+0

Dziękuję Faiz Rasool za odpowiedź: P Testowałem Spout, ale nie mogę dobrze dokumentacji o formułach, jak napisać tę formułę? $ sheet -> setCellValue ('M' $ row, '= IF (OR (CNUM (N'. $ Row. ') = 1, CNUM (N'. $ Row. ') = 2), 0,1 + CNUM (M '. $ Row.')) "); – Krokodile

+0

@Krokodile dlaczego nie robisz obliczeń w PHP i wklejasz wartość w komórce? –

+0

To jest najlepsza technika? – Krokodile

Powiązane problemy