Экспорт данных в файл CSV в Symfony - PullRequest
0 голосов
/ 18 января 2019

У меня есть консольное приложение, созданное в Symfony3, где пользователь может импортировать файл CSV (который проверяется) в базу данных. Мне нужно поместить записи, которые не прошли проверку, в отдельный файл.

Я использую LeagueCSV для чтения файла CSV и пытаюсь использовать его для записи неподтвержденных записей, но это не работает.

Это мой код:

$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();

Все записи, прошедшие проверку, успешно сохраняются в базе данных, но у меня проблема с другими записями. В новом файле CSV у меня есть только первая, одна запись, которая не прошла проверку и ничего более. Что я делаю неправильно? Я пробовал с

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

Или с ... если еще утверждение, но это ничего.

Также я сделал ... оператор else, в котором непроверенные записи сохраняются в другой таблице в базе данных и работает, но я не знаю, как немедленно преобразовать их в файл CSV.

Ответы [ 2 ]

0 голосов
/ 19 января 2019

Если вы посмотрите на страницу документа для писателя , вы увидите предупреждение вверху, которое гласит

При вставке записей в документ CSV с помощью League \ Csv \ Writer сначала вставьте все данные, которые необходимо вставить, прежде чем начинать манипулировать 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
}
0 голосов
/ 18 января 2019

Не знаю, 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);
...