Export data into CSV file in Symfony

16,458

Solution 1

Don't know symfony but CSV output is pretty simple. FWIW...

Pass this an array, like a fetchall resultset.

<?php
public function outputCSV($data, $useKeysForHeaderRow = true) {
    if ($useKeysForHeaderRow) {
        array_unshift($data, array_keys(reset($data)));
    }

    $outputBuffer = fopen("php://output", 'w');
    foreach($data as $v) {
        fputcsv($outputBuffer, $v);
    }
    fclose($outputBuffer);
}

header('Content-Type: text/csv; charset=utf-8');
header('Content-Disposition: attachment; filename="FooBarFileName_' . date('Ymd') . '.csv"');
header("Pragma: no-cache");
header("Expires: 0");
$this->outputCSV($results);

Solution 2

If you look at the doc page for the writer you will see a warning at the top which states

When inserting records into a CSV document using League\Csv\Writer, first insert all the data that need to be inserted before starting manipulating the CSV. If you manipulate your CSV document before insertion, you may change the file cursor position and erase your data.

Your code calls

$writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');              
$writer->insertOne([$row['mpn'], $row['qty'], $row['price'], $row['description']]);

In every iteration the condition is met, this appears to be overwriting or dropping your previous insert every time. You should declare the $writer once before the loop starts in order to preserve each insert.

$writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');
foreach ($results as $row) { 
  // do stuff with $writer
}
Share:
16,458
miguelsantos69
Author by

miguelsantos69

Updated on June 04, 2022

Comments

  • miguelsantos69
    miguelsantos69 almost 2 years

    I have console app made in Symfony3, where user can import CSV file (which is validate) into database. I need to put records which haven't passed validation into separate file.

    I use LeagueCSV to read CSV file and I try to use it to write unvalidated records but it doesn't work.

    This is my code:

    $reader = Reader::createFromPath($input->getArgument('lokalizacja'));
    $reader->setDelimiter(';');
    $reader->setHeaderOffset(0);
    
    $results = $reader->getRecords();
    
    foreach ($results as $row) {
    
      $year = $row['description'];
    
      $isValid = false;
    
      if ($row['qty'] > 0 && $row['price'] > 0 && !empty($row['mpn'])) {
    
          $isValid = true;
    
          $rok = filter_var($row['description'], FILTER_SANITIZE_NUMBER_INT);
    
                $product = (new Produkt())
                        ->setMpn($row['mpn'])
                        ->setQty($row['qty'])
                        ->setYear($year)
                        ->setPrice($row['price']);
    
                $this->em->persist($product); }
    
      if ($row['qty'] == 0 || $row['price'] == 0 || empty($row['mpn'])) {
    
           $writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+');              
           $writer->insertOne([$row['mpn'], $row['qty'], $row['price'], 
                          $row['description']]);
    
            continue;
      }                
    }
    
        $this->em->flush();
    

    All records which passed validation are successfully saved in the database but I have problem with others records. In new CSV file I have only first, one record which haven't passed validation and nothing more. What am I doing wrong? I tried with

    $writer->insertAll($results); //using an array
    

    Or with if...else statment but that's nothing.

    Also I made ...else statement where unvalidated records are saved in other table in database and its works but I don't know how to immediately convert them into CSV file.

    • Arleigh Hix
      Arleigh Hix over 5 years
      Try moving $writer = Writer::createFromPath('/path/to/saved/file.csv', 'w+'); before the foreach loop
    • miguelsantos69
      miguelsantos69 over 5 years
      Oh god ;D It's finally works! Thank you so much!
    • Arleigh Hix
      Arleigh Hix over 5 years
      Great! I added an answer