2015-01-04 46 views
1

我有下面的代碼用於下載由數據庫中的數據組成的Excel文件(.xls)文件。數據可能非常大,目前有20列36,000+條記錄應該傳遞給電子表格。使用PHPExcel Bundle爲Symfony2啓用細胞緩存

問題是腳本運行內存不足。目前,PHP內存限制在全局範圍內設置爲128M,但對於此特定腳本,我已將其設置爲1024M,這可防止腳本達到內存限制。由於成本的原因,我無法對服務器內存進行絕對的處理,所以我想要使用服務器上的內存。

我知道PHPExcel允許您緩存單元格以及其他性能增強功能,但是我無法將其與該包一起使用。有誰知道該怎麼做?

我正在使用的代碼是在這裏:

ini_set('max_execution_time', 600); //increase max_execution_time to 10 min if data set is very larg 
    ini_set('memory_limit', '1024M'); 

     $enviroFigures = $dm->createQuery(' 
      SELECT efu.billingCustomer, efu.division, efu.customerSite, efu.town, efu.postcode, efu.jobNumber, efu.jobStatus, efu.jobType, efu.completionDate, efu.description, efu.wasteType, efu.ewcCode, efu.container, efu.quantity, efu.disposalMethod, efu.wasteHierarchy, efu.jobNotes, efu.totalUom, efu.co2Saving, efu.customerOrderDate 
      FROM CoreBundle:EnviroFiguresUpload efu 
      WHERE efu.division IN (:profile) 
      ORDER BY efu.id DESC' 
     )->setParameter('profile', $divisionProfiles); 

     $enviFig = $enviroFigures->getResult(); 

     $excel = $this->get('phpexcel')->createPHPExcelObject(); 
     $excel->getProperties()->setCreator('iStyle') 
      ->setTitle('Resource Profile Data'); 
     $i1 = 1; 
     $excel->setActiveSheetIndex(0); 
     $excel->getActiveSheet()->setTitle('Resource Profile Data') 
       ->setCellValue('A'.$i1, 'Customer') 
       ->setCellValue('B'.$i1, 'Division') 
       ->setCellValue('C'.$i1, 'Customer Site') 
       ->setCellValue('D'.$i1, 'Town') 
       ->setCellValue('E'.$i1, 'Postcode') 
       ->setCellValue('F'.$i1, 'Job Number') 
       ->setCellValue('G'.$i1, 'Job Status') 
       ->setCellValue('H'.$i1, 'Job Type') 
       ->setCellValue('I'.$i1, 'Completion Date') 
       ->setCellValue('J'.$i1, 'Description') 
       ->setCellValue('K'.$i1, 'Waste Type') 
       ->setCellValue('L'.$i1, 'EWC Code') 
       ->setCellValue('M'.$i1, 'Total Collected') 
       ->setCellValue('N'.$i1, 'Total Co2 Saving') 
       ->setCellValue('O'.$i1, 'Container') 
       ->setCellValue('P'.$i1, 'Quantity') 
       ->setCellValue('Q'.$i1, 'Disposal Method') 
       ->setCellValue('R'.$i1, 'Waste Hierarchy') 
       ->setCellValue('S'.$i1, 'Customer Order Date') 
       ->setCellValue('T'.$i1, 'Job Notes'); 

     $i = 2; 
     for($d = 0; $d < count($enviFig); $d++) { 

       $excel->getActiveSheet() 
        ->setCellValue('A'.$i, $enviFig[$d]['billingCustomer']) 
        ->setCellValue('B'.$i, $enviFig[$d]['division']) 
        ->setCellValue('C'.$i, $enviFig[$d]['customerSite']) 
        ->setCellValue('D'.$i, $enviFig[$d]['town']) 
        ->setCellValue('E'.$i, $enviFig[$d]['postcode']) 
        ->setCellValue('F'.$i, $enviFig[$d]['jobNumber']) 
        ->setCellValue('G'.$i, $enviFig[$d]['jobStatus']) 
        ->setCellValue('H'.$i, $enviFig[$d]['jobType']) 
        ->setCellValue('I'.$i, $enviFig[$d]['completionDate']) 
        ->setCellValue('J'.$i, $enviFig[$d]['description']) 
        ->setCellValue('K'.$i, $enviFig[$d]['wasteType']) 
        ->setCellValue('L'.$i, $enviFig[$d]['ewcCode']) 
        ->setCellValue('M'.$i, $enviFig[$d]['totalUom']) 
        ->setCellValue('N'.$i, $enviFig[$d]['co2Saving']) 
        ->setCellValue('O'.$i, $enviFig[$d]['container']) 
        ->setCellValue('P'.$i, $enviFig[$d]['quantity']) 
        ->setCellValue('Q'.$i, $enviFig[$d]['disposalMethod']) 
        ->setCellValue('R'.$i, $enviFig[$d]['wasteHierarchy']) 
        ->setCellValue('S'.$i, $enviFig[$d]['customerOrderDate']) 
        ->setCellValue('T'.$i, $enviFig[$d]['jobNotes']); 
       $i++; 
      } 


     // create the writer 
     $writer = $this->get('phpexcel')->createWriter($excel, 'Excel5'); 
     // create the response 
     $response = $this->get('phpexcel')->createStreamedResponse($writer); 
     // adding headers 
     $response->headers->set('Content-Type', 'text/vnd.ms-excel; charset=utf-8'); 
     $response->headers->set('Content-Disposition', 'attachment;filename=stream-file.xls'); 
     $response->headers->set('Pragma', 'public'); 
     $response->headers->set('Cache-Control', 'maxage=1'); 

     return $response; 
+0

是否必須是一個電子表格?看起來像一個csv文件可能就足夠了。 – Cerad

+0

首先,將getResult()方法切換到getArrayResult(),所以Doctrine不會爲所有結果提供不需要的數據。這可能是你記憶力問題的第一個原因(但不一定是唯一原因)。 – sjagr

回答

1

包就位於原來PHPExcel庫的包裝。 該庫的所有設置(還有緩存設置)都存儲在PHPExcel_Settings類的靜態屬性中。因此,要設置緩存,你可以簡單地使用下面的代碼:

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_phpTemp; 
$cacheSettings = array('memoryCacheSize ' => '256MB'); 
PHPExcel_Settings::setCacheStorageMethod($cacheMethod, $cacheSettings); 

或者,如果你想要內存緩存:

$cacheMethod = PHPExcel_CachedObjectStorageFactory::cache_to_memcache; 
$cacheSettings = array('memcacheServer' => 'localhost', 'memcachePort' => 11211, 'cacheTime' => 600); 
+0

我嘗試了第一個代碼(我使用APC,所以不想使用memcache),並且在Apache日誌中出現錯誤:[Sun Jan 04 09:11:09 2015] [error] [client 90.244.111.215] PHP致命錯誤:在第174行的/var/www/src/CWWA/CoreBundle/Controller/DownloadController.php中找不到類「CWWA \\ CoreBundle \\ Controller \\ PHPExcel_CachedObjectStorageFactory」,引用者:https: // portal.circom.co.uk/client/dashboard /' – mickburkejnr

+1

嘗試命名空間版本'\ PHPExcel_CachedObjectStorageFactory'。如果它不會幫助 - 請檢查您的自動加載。 – Ziumin