简体   繁体   English

在 Symfony 中将数据导出为 CSV 文件

[英]Export data into CSV file in Symfony

I have console app made in Symfony3, where user can import CSV file (which is validate) into database.我有在 Symfony3 中制作的控制台应用程序,用户可以在其中将 CSV 文件(已验证)导入数据库。 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.我使用 LeagueCSV 读取 CSV 文件,并尝试使用它来写入未经验证的记录,但它不起作用。

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.在新的 CSV 文件中,我只有第一个,一个没有通过验证的记录,仅此而已。 What am I doing wrong?我究竟做错了什么? I tried with我试过

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

Or with if...else statment but that's nothing.或者使用 if...else 语句,但这没什么。

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.我还做了 ...else 语句,其中未经验证的记录保存在数据库中的其他表及其作品中,但我不知道如何立即将它们转换为 CSV 文件。

Don't know symfony but CSV output is pretty simple.不知道 symfony 但 CSV 输出非常简单。 FWIW... FWIW...

Pass this an array, like a fetchall resultset.传递一个数组,就像一个 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);

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.使用 League\\Csv\\Writer 向 CSV 文档插入记录时,在开始操作 CSV 之前,首先插入所有需要插入的数据。 If you manipulate your CSV document before insertion, you may change the file cursor position and erase your data.如果您在插入之前操作您的 CSV 文档,您可能会更改文件光标位置并删除您的数据。

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 = Writer::createFromPath('/path/to/saved/file.csv', 'w+');
foreach ($results as $row) { 
  // do stuff with $writer
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM