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

ssquare's avatar

Import CSV file, remove empty rows and export it immediately without storing it into database - laravel excel

I am trying to remove all the empty rows from a csv and make it downloadable. In this process, there is no involvement of database/model.

My flow looks like:

  1. Import csv file.
  2. Filter empty rows.
  3. Export the data after all the empty rows are removed.

My code looks like:

#Controller

    public function formatCSV()
    {
        $path = storage_path('app/files/') . 'example.csv';
        Excel::import(new FormatCSV, $path);
    }

#app/Imports/FormatCSV

<?php


namespace App\Imports;


use App\Exports\ExportFormattedCSV;
use App\Http\Services\AmenityService;
use Maatwebsite\Excel\Concerns\ToArray;
use Maatwebsite\Excel\Concerns\WithChunkReading;
use Excel;

class FormatCSV implements ToArray, WithChunkReading
{
    private $table,$service,$model;
    public function __construct()
    {
        $this->service = new AmenityService();
    }
    public function array(Array $rows)
    {   $rec_arr = array();
        foreach ($rows as $row)
        {
            $rec_arr[] = array_values($row);
        }
        $records_arr = $this->service->trimArray($rec_arr);

        $export = new ExportFormattedCSV($records_arr);
        //print_r($export);
        return Excel::download($export, 'csv.csv');
    }

    public function chunkSize(): int
    {
        return 10;
    }

}

#app/Exports/ExportFormattedCSV

<?php


namespace App\Exports;

use Maatwebsite\Excel\Concerns\FromArray;

class ExportFormattedCSV implements FromArray
{
    protected $data;

    public function __construct(array $data)
    {
        $this->data = $data;
    }
    public function array(): array
    {
        return $this->data;
    }

}

With this code it does nothing, shows blank at the end.

However, if I uncomment the line print_r($export)

It shows data as:

App\Exports\ExportFormattedCSV Object
(
    [data:protected] => Array
        (
            [0] => Array
                (
                    [0] => First Name
                    [1] => Last Name
                    [2] =>  Roll No
                )

            [1] => Array
                (
                    [0] => Ram
                    [1] => Patel
                    [2] => 1
                )

            [2] => Array
                (
                    [0] => Rajuv
                    [1] => Roy
                    [2] => 2
                )

            [3] => Array
                (
                    [0] => Sunny
                    [1] => Deol
                    [2] => 5
                )

            [4] => Array
                (
                    [0] => Akshya
                    [1] => Kumar
                    [2] => 6
                )

            [5] => Array
                (
                    [0] => Amir Khan
                    [1] => 7
                    [2] => 
                )

            [6] => Array
                (
                    [0] => Salman
                    [1] => Khan
                    [2] => 9
                )

            [7] => Array
                (
                    [0] => Bobby
                    [1] => Deol
                    [2] => 10
                )

        )

)

The File I am testing is example.csv

First Name,Last Name, Roll No
Ram,Patel,1
Rajuv,Roy,2
,,
Sunny,Deol,5
Akshya,Kumar,6
Amir Khan,7
,,
Salman,Khan,9
Bobby,Deol,10,
Barun,Dhawan,11
,,
Virat,Kohli,13
Rohit,Sharma,14

And trimArray function :

    public function trimArray($arr)
    {
        $final = array();

        foreach($arr as $k => $v)
        {
            if(array_filter($v)) {
                $final[] = $v;
            }
        }

        return $final;

    }
0 likes
5 replies
bobbybouwmann's avatar

The problem here is that you convert everything first before you start filtering on empty lines. The trimming/filtering should already be done before you create the new array. You can, for example, check if $rows[0] === , if so, skip the row.

public function array(Array $rows)    
{   
    $records = [];

    foreach ($rows as $row) {
        if ($row[0] === '' || $row[0] === null) {
            continue;
        }

        $records[] = array_values($row);
    }

    $export = new ExportFormattedCSV($records_arr);

    return Excel::download($export, 'csv.csv');
}
1 like
ssquare's avatar

@bobbybouwmann I have done as you mentioned. However, still the same issue.

Also, my main issue is not about filtering. As even with my old method it is filtering empty rows. However, it is not forcing to download.

So far, my guess is that on the documentation it has mentioned that the array function of Import class would never return anything. Could that be the reason for not downloading CSV file?

bobbybouwmann's avatar

Yeah! You cannot have both worlds in this case. You need to import the file and store it on the server somewhere. Then fetch it again and give it to the download method.

ssquare's avatar

@bobbybouwmann any other hacks or suggestions to make this workout. I am open to the suggestion of some other package as well.

bobbybouwmann's avatar

You can do everything in one request, but you first need to save the file somewhere and retrieve it again before you give a download response. That's the only workaround there is.

Please or to participate in this conversation.