Export data into CSV file in Symfony

时间:2019-01-18 19:08:59

标签: php symfony csv export-to-csv

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.

2 个答案:

答案 0 :(得分:0)

不知道symfony,但是CSV输出非常简单。 FWIW ...

将其传递给数组,例如fetchall结果集。

<?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);

答案 1 :(得分:0)

如果您查看the doc page for the writer,则会在顶部看到一条警告,提示您

  

使用League \ Csv \ Writer将记录插入到CSV文档中时,请先插入所有需要插入的数据,然后再开始操作CSV。如果您在插入文件之前先处理CSV文档,则可以更改文件光标的位置并删除数据。

您的代码调用

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

在每次迭代中都满足条件,这似乎是每次都覆盖或删除您先前的插入内容。您应该在循环开始之前声明一次$writer,以保留每个插入内容。

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