2015-01-04 1 views
1

데이터베이스의 데이터로 구성된 Excel 파일 (.xls) 파일을 다운로드하는 데 사용되는 다음 코드가 있습니다. 데이터가 매우 클 수 있으며 현재 스프레드 시트로 전달되어야하는 36,000 개 이상의 레코드가있는 20 개의 열이 있습니다.Symfony2 용 PHPExcel Bundle을 통한 셀 캐싱 사용

문제는 스크립트의 메모리가 부족한 것입니다. 현재 PHP 메모리 제한은 전 세계적으로 128M로 설정되어 있지만이 특정 스크립트의 경우 1024M로 설정했기 때문에 스크립트가 메모리 제한을 초과하는 것을 방지합니다. 비용 때문에 나는 서버 RAM에 절대적으로 미칠 수 없었으므로 서버에있는 RAM과 효율적으로 작업하고 싶습니다.

필자는 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); 

아니면 memcache를 원하는 경우 :

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

나는 첫 번째 비트의 코드 (APC를 사용하고 있으므로 memcache도 사용하고 싶지 않았다.)를 시도했는데 아파치 로그에 오류가 발생했다 :'[Sun Jan 04 09:11:09 2015] [오류] [client 90.244.111.215] PHP 치명적 오류 : 클래스 'CWWA \\ CoreBundle \\ Controller \\ PHPExcel_CachedObjectStorageFactory'가 /var/www/src/CWWA/CoreBundle/Controller/DownloadController.php에서 찾을 수 없습니다. referer : https : // portal.circom.co.uk/client/dashboard /' – mickburkejnr

+1

네임 스페이스 버전'\ PHPExcel_CachedObjectStorageFactory'을 사용해보십시오. 도움이되지 않으면 자동로드를 확인하십시오. – Ziumin