Как экспортировать Excel с 60k+ строк в Laravel

У меня есть файл, который загружает Excel в Laravel 4.2

страница просмотра выглядит следующим образом

    ini_set('memory_limit', '-1');
    require(app_path().'/libs/excel/Classes/PHPExcel.php');
    $objPHPExcel = new PHPExcel();

    // Set document properties
    $objPHPExcel->getProperties()->setCreator("ideconnect.com")
                                 ->setLastModifiedBy("ideconnect.com")
                                 ->setTitle("Office 2007 XLSX Test Document")
                                 ->setSubject("Office 2007 XLSX Test Document")
                                 ->setDescription("Test document for Office 2007 XLSX, generated using PHP classes.")
                                 ->setKeywords("office 2007 openxml php")
                                 ->setCategory("Test result file");

    $arr = array();

            $users1 = User::where('event','=',$exceleve)->orderby('name')->with(array('answer'=>function($q) use($qid1){

                $q->where('question_id','=','3104')->orWhere('question_id','=','3105');

            }))->get();

    $user_ids=array();
    foreach($users1 as $us){
        if($us->answer[0]->answer_text!='' && ($us->role!='admin_dd' || $us->role!='sales_dd')){
            $user_ids[] = $us->id;
        }
    }

        $userswithanswers = User::whereIn('id', $user_ids)
                        ->with('answer')
                        ->get();


    foreach($userswithanswers as $usa){

        $tempansarr = array();
        $tempcatansarr = array();

        foreach($usa->answer as $ansobj){
            $tempansarr[$ansobj->question_id] = $ansobj->answer_text;
        }

        foreach($usa->categoryvendoranswer as $catansobj){
            $tempcatansarr[$catansobj->categoryvendor_id] = $catansobj->answer;
        }

        $useransarr[$usa->id]['login'] = $usa->email;
        $useransarr[$usa->id]['id'] = $usa->id;
        $useransarr[$usa->id]['answers'] = $tempansarr;
        $useransarr[$usa->id]['catanswers'] = $tempcatansarr;
     //dd($tempcatansarr);
    }

    $questions = Question::orderBy('page')->where('event' ,'=',$exceleve)->where('page' ,'!=',0)->orderBy('order')->get();
    //$categoryvendors = Categoryvendor::all();


    // HEADER ROW FOR FOR EXCEL
    $header1 = array();$header1[]='';
    $header2 = array();$header2[]='Login';
    $preprojectnumber = '';

    foreach($questions as $header){
        /*echo $header->class_name."<br>";
        echo $header->question_group."<br>";*/
        $header3[] = "Page_".$header->page;
        if($header->class_name !='projects checkbox group'){
            //echo "1";
            $header1[] = $header->question_group;
            $header2[] = $header->question_text;

        } else {
            if($header->question_group!=$preprojectnumber){
                $header1[] = $header['question_group'];
                $header2[] = 'Stage of Buying Cycle';

            }
            $preprojectnumber = $header->question_group;

        }

    }

$excelarr = array();
//dd($useransarr);


foreach($useransarr as $usarr){

        $b=array();
        $b[]=$usarr['login'];
        $preprojectnumber = '';
        $tempvar = '';
        $counter=0;

// dd($usarr['answers']);

    foreach($questions as $question){
            if($question->class_name!='projects checkbox group'){ 
                $b[] = $usarr['answers'][$question->id];
            } 
            else 
            {
                if($question->question_group!=$preprojectnumber){
                    $counter=1;
                    $tempvar = $usarr['answers'][$question->id];
                    if($usarr['answers'][$question->id]!=''){$tempvar = $tempvar.', ';}
                } else {
                    $tempvar = $tempvar.$usarr['answers'][$question->id];
                    if($usarr['answers'][$question->id]!=''){$tempvar = $tempvar.', ';}
                }
                    $preprojectnumber = $question->question_group;
                    $counter++;
                    if($counter==5){
                            $b[]=$tempvar;
                    }
            }
    }
    $excelarr[] = $b;
}

array_unshift($excelarr, $header1);
array_unshift($excelarr, $header2);

$objPHPExcel->setActiveSheetIndex(0)
            ->fromArray($excelarr, '', 'A1');

$objPHPExcel->getActiveSheet()->setTitle($exceleve);

$styleArray = array(
      'font' => array(
        'name' => 'Calibri',
        'size' => '10',
        'color' => array(
            'rgb' => 'FFFFFF'
        ),
        'bold' => true,
      ),
      'fill' => array(
        'type' => PHPExcel_Style_Fill::FILL_SOLID,
        'startcolor' => array(
          'rgb' => '000000',
        ),
      ),
    );


$styleArray2 = array(
      'font' => array(
        'name' => 'Calibri',
        'size' => '10',
        'color' => array(
            'rgb' => '000000'
        ),
        'bold' => true,
      ),

      'fill' => array(
        'type' => PHPExcel_Style_Fill::FILL_SOLID,
        'startcolor' => array(
          'rgb' => 'cccccc',
        ),
      ),
    );

$styleArray3 = array(
      'font' => array(
        'name' => 'Calibri',
        'size' => '8',
        ),
    );


$objPHPExcel->setActiveSheetIndex(0)->getDefaultStyle()->applyFromArray($styleArray3);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('A2:LA2')->applyFromArray($styleArray2);
$objPHPExcel->setActiveSheetIndex(0)->getStyle('A1:LA1')->applyFromArray($styleArray);

$objPHPExcel->setActiveSheetIndex(0);

header('Content-Type: application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
header('Content-Disposition: attachment;filename="event-data.xlsx"');
header('Cache-Control: max-age=0');


$objWriter = PHPExcel_IOFactory::createWriter($objPHPExcel, 'Excel2007');


 // dd('aaa');
//ob_end_clean();
$objWriter->save('php://output');

exit;

Этот код работает очень хорошо, если количество строк меньше, но если данные увеличиваются, он выбрасывает

Memory Limit reach

Я просто хочу знать, размещение этого кода внутри очереди решит проблему??

если да, то как мне это поставить

Спасибо

1 ответ

Вы должны попробовать реализовать Cell Caching, как описано здесь: https://github.com/PHPOffice/PHPExcel/blob/develop/Documentation/markdown/Overview/04-Configuration-Settings.md#cell-caching

Вместо того, чтобы пытаться сохранить все данные в памяти, некоторые из них будут кэшироваться на диске или в базе данных. Это уменьшает объем памяти, необходимый PHPExcel. Недостаток заключается в том, что обработка теперь будет занимать больше времени (и она выглядит экспоненциальной).

В качестве альтернативы вы можете попробовать использовать Spout: https://github.com/box/spout. Он может анализировать таблицы независимо от их размера, используя не более 3 МБ памяти. Вы не найдете столько функций, сколько в PHPExcel, но все функции, которые вы использовали в своем примере, похоже, поддерживаются.

Другие вопросы по тегам