10

I have a CSV file where the data is in landscape orientation.ex:

name, test name
age, 20
gender,Male

where the first column is the headers and the second the data, i tried using laravel maatwebsite/Excel and the response after reading the file, the first row is taken as the headers. (name and test name).

is there any method to read this type of CSV files in laravel using maatwebsite/Excel

Naveed Sheriffdeen
  • 940
  • 6
  • 18
  • 37
  • 2
    That's just a badly formed csv. Almost all csv specs define records per line and fields of that record separated by a delimiter. – Devon Bessemer Oct 23 '18 at 11:58

4 Answers4

20

You can use this function

public function readCSV($csvFile, $array)
{
    $file_handle = fopen($csvFile, 'r');
    while (!feof($file_handle)) {
        $line_of_text[] = fgetcsv($file_handle, 0, $array['delimiter']);
    }
    fclose($file_handle);
    return $line_of_text;
}
$csvFileName = "test.csv";
$csvFile = public_path('csv/' . $csvFileName);
$this->readCSV($csvFile,array('delimiter' => ','))
Dharman
  • 30,962
  • 25
  • 85
  • 135
Sagar Patel
  • 394
  • 1
  • 2
  • 11
7

You don't need an entire library. PHP has a built-in function http://php.net/manual/en/function.str-getcsv.php

online Thomas
  • 8,864
  • 6
  • 44
  • 85
3

It doesn't matter for such small CSVs, but try to demand of those who give you CSVs to have them properly formatted, and not transposed or use online solutions to do so yourself. Here's the solution, but it stores the entire array in memory, even though the package in the first example is specifically made to avoid that.

With composer

You may use Spatie's simple-excel like so:

$csv = __DIR__ . '/data.csv';
$data = [];
SimpleExcelReader::create($csv)
    // ->useDelimiter(';') // Optional
    ->noHeaderRow() // Optional
    ->getRows()
    ->each(function(array $row) use (&$data) {
        $length = count($row);
        for ($i = 1; $i < $length; $i++) {
            $data[$i - 1] ??= [];
            $data[$i - 1][$row[0]] = $row[$i];
        }
});

I also opened an issue for your use-case. (Issue was closed, due to the solution not being memory efficient)

Without composer

As said by "online Thomas", there's a native PHP function for that, and I find it easiest to use it, in general, like so:

$csv = __DIR__ . '/data.csv';
$data = array_map('str_getcsv', file($csv));

Caveat: does not produce the desired results, if fields contain linebreaks

Use closure in your case, or if you need a delimiter other than ',', etc.:

$csv = __DIR__ . '/data.csv';
$data = [];
array_map(function ($line) {
    $row = str_getcsv($line);
    $length = count($row);
    for ($i = 1; $i < $length; $i++) use (&$data) {
       $data[$i - 1] ??= [];
       $data[$i - 1][$row[0]] = $row[$i];
    }
}, file($csv));
s3c
  • 1,481
  • 19
  • 28
0

For 2022 readers: what I am using right now is: https://github.com/spatie/simple-excel

work like a charm with no memory usage due to LazyCollections

Jack
  • 489
  • 1
  • 6
  • 18