2011-08-11 19 views
8

Próbuję przechodzić przez 3-milimetrowy dokument Excel, aby uzyskać wszystkie dane, które będę następnie musiał wstawić do bazy danych. Arkusz, którego używam, ma 6500 wierszy, ale może się różnić w przyszłości. Zauważyłem, że chociaż używam zalecanych technik oszczędzania pamięci, to wciąż faulujeProblem z pamięcią PHPExcel

$reader = PHPExcel_IOFactory::createReaderForFile($file_path); 
$reader->setReadDataOnly(true); 

//$sheets = $this->getWorksheetNames($file['tmp_name'], 0); 
$reader->setLoadSheetsOnly('spreadsheetname'); 

$chunkFilter = new IPO_Reader(); 
$reader->setReadFilter($chunkFilter); 

$highestRow = 10000; //$this->objWorksheet->getHighestRow(); 
$chunkSize  = 1; 
$highestColumn = "Y"; 

for ($startRow = 2; $startRow <= $highestRow; $startRow += $chunkSize) 
{ 

    $chunkFilter->setRows($startRow, $chunkSize); 
    $objPHPExcel = $reader->load($file_path); 

    for($row = $startRow ; $row <= $startRow + $chunkSize; $row++) 
    { 
     $this->read_row = $objPHPExcel->getActiveSheet()->rangeToArray('A'.$row.':'.$highestColumn.$row, null, true, true, true); 

     $this->read_row = end($this->read_row);   

     foreach($this->read_row as $column => $value) 
     { 
      $db_column_name = $this->_getDbColumnMap($column); 
      if(!empty($db_column_name)) 
      { 
       $this->new_data_row[$db_column_name] = $this->_getRowData($value, $column); 
      } 

     } 

     $this->read_row = null; 
     $this->new_data_row['date_uploaded'] = date("Y-m-d H:i:s"); 
     $this->new_data_row['source_file_name'] = $file_name; 
     $ipo_row = new Model_UploadData_IPO(); 
     $ipo_row->create($this->new_data_row); 
     $this->new_data_row = null; 
     unset($ipo_row); 

     gc_collect_cycles(); 

    } 
    $objPHPExcel->disconnectWorksheets(); 
    unset($objPHPExcel);  
    gc_collect_cycles(); 

kiedy przetestować zużycie pamięci zanim rozbroić objPHPExcel i po, nie ma wzmocnienia pamięci, jestem bardzo zdezorientowany, ponieważ podzielenie na porcje nie pozwala mi wyczyścić pamięci po każdym kawałku, a użycie stopniowo wzrasta, a przy limicie ustawionym na 250 MB, pozwala mi tylko dodać ~ 500 rekordów

+0

i nie ostatni problem =) po prostu spojrzeć na http://stackoverflow.com/questions/6857075/problem-with-excell-export (jeść 500MB) – Subdigger

+0

Niestety brakowało połowa tam zdanie. pozwala mi dodać tylko 500 rekordów –

+0

Kasia: możesz edytować swoje pytania, jeśli popełnisz błąd – Mchl

Odpowiedz

3

PHP excel library is known to have these memory issues, miałem też z tym problem. Co pracował dla mnie była to rada (z powyższego linku, spróbuj, istnieją dobre porady, jak zmniejszyć zużycie pamięci):

$objReader = new PHPExcel_Reader_Excel5(); 
$objReader->setReadDataOnly(true); /* this */ 

Ale mimo to wymogi pamięciowe są duże, ponieważ przeznaczyć dużo pamięci dla każdej komórki (do formatowania itp., nawet jeśli nie jest to potrzebne). Obawiam się, że jesteśmy bezradni, dopóki nie wydadzą nowej wersji biblioteki.

0

Ok, wszyscy wiedzą, że trwtf to Excel, więc czy mogę go przekonwertować na CSV?

Mam swój własny CSV do funkcji tabel w PHP, które były używane do importowania bardzo dużych plików, CSV wydaje się być znacznie lżejszy w przetwarzaniu, a także znacznie mniej podatny na przypadkowe problemy z bibliotekami.

Jeśli naprawdę potrzebujesz tego do jednorazowego procesu lub możesz przejść z XLS do CSV dość łatwo, zrób to, ponieważ znacznie ułatwi Ci to życie (jak zawsze będziesz trzymać się prostszych, bardziej standardowych alternatyw;)) .

I tak przez API, które przełoży się jakże zły i straszny formacie XLS, można użyć jednego z konwerterów w kolejnym O/S - Polecam Python za każdym razem, ale hej, swój wybór:

http://www.oooninja.com/2008/02/batch-command-line-file-conversion-with.html

http://code.google.com/p/jodconverter/wiki/FAQ

Zasadniczo pomysł jest taki sam, należy użyć zewnętrznego narzędzia w celu uzyskania użytecznego formatu pliku, a następnie udać się stamtąd.

Nie sądzę, żebym miał tutaj mój skrypt csvtotable.php, ale można go łatwo replikować, wystarczy mieć kilka podstawowych narzędzi, takich jak csvtoarray, a następnie arraytoinsertstatements.

GL;)

+1

Chciałbym po prostu wgrać pliki CSV, ale niestety nie tego chce klient. –

+0

OK, mam rozwiązanie również ... A co z autobusem? - nie żartuję z OpenOffice API, może to zrobić dość łatwo imo - linki w głównym poście –

+0

Podczas mojej ostatniej pracy, miałem również problem z PHPExcel i problemy z pamięcią z dużymi plikami Excel. Podczas ich lektury wciąż miałem problemy, ponieważ niektórzy z naszych dostawców przesyłają pliki o rozmiarze 20 MB +. Jeśli dobrze pamiętam, ja również użyłem OpenOffice API, aby otworzyć plik i przekonwertować go do CSV, a następnie użyć nowego pliku do iteracji i wstawiania rekordów do mojego DB. Już wcześniej zaoferowałem naszym użytkownikom możliwość przesyłania plików OpenOffice Calc, więc miałem już kod. Jeśli działa to przy użyciu OpenOffice, chcielibyśmy zobaczyć Twoje rozwiązanie. – MB34

Powiązane problemy