Be part of JetBrains PHPverse 2026 on June 9 – a free online event bringing PHP devs worldwide together.

Inquisitive's avatar

Allowed memory size of 134217728 bytes exhausted (tried to allocate 20971520 bytes) - Laravel excel

I have a file and, there are a lot of empty columns and rows, and I want to remove those and only keep those rows and columns which are needed.

It was working fine, until I got this file. It is throwing allowed memory size exceeded issue.

Here is the code:

public function formatCSV(Request $request){
    $data = [
        'file_name' =>$request->filename,
        'header_row' => $request->header_row,
    ];
    return Excel::download(new ExportFormattedCSV($data), $request->filename);
}

and this ExportFormattedCSV is:

<?php


namespace App\Exports;

use App\Imports\FormatCSV;
use Maatwebsite\Excel\Concerns\FromArray;
use Excel;
use Maatwebsite\Excel\Concerns\WithEvents;
use Maatwebsite\Excel\Events\AfterSheet;
use Maatwebsite\Excel\Concerns\RegistersEventListeners;

class ExportFormattedCSV implements FromArray,WithEvents
{
    use RegistersEventListeners;
    protected $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }
    public function array(): array
    {
        $path = storage_path('app/files/scrubber/') . $this->data['file_name'];
        $arr = Excel::toArray(new FormatCSV(), $path);
        $arr = array_shift($arr);

        //header is fixed at 7 (although it may seems 10)
        $arr = array_slice($arr, 7);
        array_pop($arr);
        array_pop($arr);

        $rec_arr = $empty_col = array();
        $empty_col_checked = false;
        foreach ($arr as $ak=>$av){
                if(count(array_filter($av)) != 0){
                    if(!$empty_col_checked){
                        foreach($av as $k => $v){
                            if($v == ''){
                                $empty_col[] = $k;
                            }
                        }
                        $empty_col_checked = true;
                    }
                    $rec_arr[] = $av;
                }
        }

        foreach($empty_col as $ek => $ev){
            if(empty( array_filter(array_column($rec_arr,$ev))) )
            {
                foreach($rec_arr as &$item) {
                    unset($item[$ev]);
                }
                unset($item);
            }
        }

        $pre_val = '';
        $format_header = true;

        foreach ($rec_arr as $ak => $av) {
            foreach ($av as $k => $v) {
                if($ak === 0){
                    if($k === 18){
                        if(stripos($v, 'unit') !== false && stripos($v, 'sqft') !== false){
                            $unit_col = $k;
                        }
                    }
                }

                if ($v == '' && $k == 0) {
                    $rec_arr[$ak][$k] = $pre_val;
                } elseif ($k == 0){
                    $pre_val = $v;
                }

                if(isset($unit_col)){
                    if ($v == '' && $k == $unit_col) {
                        $rec_arr[$ak][$k] = $pre_sqft;
                    } elseif ($k == $unit_col){
                        $pre_sqft = $v;
                    }
                }

                if($format_header){
                    $rec_arr[$ak][$k] = trim(preg_replace('/\s+/', ' ', $v));;
                }
            }
            if($rec_arr[0][45] != "" && $rec_arr[0][44] == ""){
                $rec_arr[0][44] =  trim($rec_arr[0][45]);
                $rec_arr[0][45] = "";
            }
            $format_header = false;
        }

        return $rec_arr;
    }

    public static function afterSheet(AfterSheet $event)
    {
        $active_sheet = $event->sheet->getDelegate();
        $centered_text = [
            'alignment' => [
                'horizontal' => \PhpOffice\PhpSpreadsheet\Style\Alignment::HORIZONTAL_CENTER, 'vertical' => \PhpOffice\PhpSpreadsheet\Style\Alignment::VERTICAL_CENTER
            ]
        ];
        $active_sheet->getParent()->getDefaultStyle()->applyFromArray($centered_text);

    }
}

and that FormatCSV is pretty much empty and looks like this:

<?php

namespace App\Imports;

use Illuminate\Support\Collection;
use Maatwebsite\Excel\Concerns\ToCollection;

class FormatCSV implements ToCollection
{

    public function collection(Collection $rows)
    {
        foreach ($rows as $row)
        {

        }
    }
}

Basically, it seems to be throwing the error at this line:

$arr = Excel::toArray(new FormatCSV(), $path);

I have also tried with queue by implementing ShouldQueue, but this is storing empty file with no data at all.

Also, the file doesn't have much rows its just about 7000 rows.

Could I be doing anything wrong? Why its showing blank with queue? With queue, I am just implementing that ShouldQueue and calling that export class as:

Excel::store(new ExportFormattedCSV($data),$data['file_name']);
0 likes
9 replies
sr57's avatar

easiest way is to see if the pb is solved by increasing the memory size, for instance

in php.ini or in your code ini_set('memory_limit';; '1024M');

Compare if the size of your file is (far) blow the size of your memory limit

Inquisitive's avatar

@sr57 Its because upto just before that line, I could dd('hit) but I couldn't just after that line. That's the reason why I am saying that.

This is what showing on storage/logs

[2022-04-21 02:54:55] local.ERROR: Allowed memory size of 134217728 bytes exhausted (tried to allocate 20971520 bytes) {"userId":2,"exception":"[object] (Symfony\Component\ErrorHandler\Error\FatalError(code: 0): Allowed memory size of 134217728 bytes exhausted (tried to allocate 20971520 bytes) at /var/www/project/vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php:415)
[stacktrace]
#0 {main}
"} 
sr57's avatar

@Inquisitive

Ok, good, you should have written without seems :-)

That said, you can do the same method in vendor/phpoffice/phpspreadsheet/src/PhpSpreadsheet/Collection/Cells.php

Log memory usage with a cell identifier (data if needed) and you should find the root cause.

Inquisitive's avatar

Okay, will do it, but could there be a proper way of chunking or loading those array in chunk on memory?

sr57's avatar

@Inquisitive

Don't understand your wrote your file is small (~300Kb) ....

That's said another method should be to split your file by 2, recursively ...

Inquisitive's avatar

@sr57 What I am trying to say is that $arr = Excel::toArray(new FormatCSV(), $path); this code will return an array, and when it is huge, it is throwing an allocation memory issue. Is there any way, instead of returning the full array at once, can we return it on the chunk and write it on CSV on the chunk?

I can see the chunk options on laravel excel, but it seems to be importing to model directly, instead of importing to model to directly, could I import to array (on first 500) rows and then send these row to export, on next fetch another 500rows and append it to the same exported excel and so on....

Please or to participate in this conversation.