如何将数据写入csv文件?

时间:2013-01-11 14:34:30

标签: php magento

例如:csv有两列。结构是:它只有标题。

sku name

现在,有一个foreach循环:

foreach ($collection as $product_all) 
{
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);
    $name = $product['name'];
}

如果有8000行,我想将$sku$name放入csv文件中。我该怎么办?我使用以下代码。但它不起作用。怎么纠正呢?谢谢。

foreach ($collection as $product_all) 
{
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);   
    $name = $product['name'];
    $newCsvData = array();
    if (($handle = fopen("test.csv", "r")) !== FALSE) 
    {
        while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) 
        {
            $data[0] = $sku;
            $data[2] = $name;
            $newCsvData[] = $data;
        }
        fclose($handle);
    }

    $handle = fopen('test.csv', 'w');
    foreach ($newCsvData as $line) 
    {
        fputcsv($handle, $line);
    }

    fclose($handle);
}

4 个答案:

答案 0 :(得分:2)

没试过,但它应该有用。

$csvData = array();
foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);   
  $name = $product['name'];

  $csvData[] = array($sku, $name);
}


$handle = fopen('test.csv', 'w');
fputcsv($handle, array('sku', 'name'));
foreach($csvData as $row) {
  fputcsv($handle, $row);
}
fclose($handle);

fputcsv函数会为您完成所有转义操作,如果您希望csv文件可以在任何输入中工作,这不是一件小事。

在阅读其他答案的一些评论后,您可以在循环中移动fputcsv来电:

$handle = fopen('test.csv', 'w');
fputcsv($handle, array('sku', 'name'));

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);   
  $name = $product['name'];

  fputcsv($handle, array($sku, $name));
}

fclose($handle);

答案 1 :(得分:1)

我能想到的最简单的解决方案:

// The filename to write to
$csvFile = 'theCSVfile.csv';
$csvRows = array();

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);
  // Replacing quotation marks with CSV escaped ones
  $name = str_replace( '"' , '""' , $product['name'] );

  $csvRows[] = "{$sku},\"{$name}\"";
}

file_put_contents( $csvFile , implode( "\n" , $csvRows ) );

请记住,如果$name变量包含逗号或其他异常字符,则可能会产生无效的CSV语法。

Bogdan 所述,这可能是内存密集型的,因为它涉及在对文件执行单次写入之前保留RAM中的所有行。如果这是一个问题,或者您正在处理大量的行,则以下代码将写入批处理为较小的块。

// The filename to write to
$csvFile = 'theCSVfile.csv';
// Rows per chunk
$csvChunk = 1000;

// Initialise the Array
$csvRows = array();
// Variable to check if first write performed
$firstWriteDone = false;

function writeChunk(){
  global $csvFile, $csvRows, $csvChunk, $firstWriteDone;

  if( count( $csvRows )==$csvChunk ){
    // Chunk Limit Reached - Write to disk
    file_put_contents(
      $csvFile ,
      ( !$firstWriteDone ? "\n" : '' ) . implode( "\n" , $csvRows ) ,
      ( !$firstWriteDone ? FILE_APPEND : 0 )
    );
    // Set the First Write Done flag
    $firstWriteDone = true;
    // Reset the Array
    $csvRows = array();
  }
}

foreach ($collection as $product_all) {
  $sku = $product_all['sku'];
  $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
  $product    = Mage::getModel('catalog/product');
  $product ->load($product_id);
  // Replacing quotation marks with CSV escaped ones
  $name = str_replace( '"' , '""' , $product['name'] );

  $csvRows[] = "{$sku},\"{$name}\"";

  if( count( $csvRows )==$csvChunk ){
    // Chunk Limit Reached - Write to disk
    writeChunk();
  }
}
if( count( $csvRows ) ){
  // Write the Last Chunk, even if not at the limit
  writeChunk();
}

答案 2 :(得分:0)

你的代码搞砸了男人...... 对于每个数据库条目..你读csv ..从它收集日期(没有?) 并将其“写”到csv ..

修复您的代码:

    $newCsvData = array();

    foreach ($collection as $product_all) { 
        $sku = $product_all['sku'];

        $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);

        $product = Mage::getModel('catalog/product');

        $product->load($product_id);

        $name = $product['name'];

        //move BEFORE the foreach
        /*$newCsvData = array();*/

        //remove this ...
        /*if (($handle = fopen("test.csv", "r")) !== FALSE) {
            while (($data = fgetcsv($handle, 1000, ",")) !== FALSE) {
                $data[0] = $sku;
                $data[2] = $name;
                $newCsvData[] = $data;
            }
            fclose($handle);
        }*/

        //move AFTER the foreach
        /*
        $handle = fopen('test.csv', 'w');

        foreach ($newCsvData as $line) {
            fputcsv($handle, $line);
        }

        fclose($handle);*/
    }

    $handle = fopen('test.csv', 'w');

    foreach ($newCsvData as $line) {
        fputcsv($handle, $line);
    }

    fclose($handle);

检查其他示例,他们可能更好,只是想知道你的代码有什么问题。

答案 3 :(得分:0)

在迭代产品集合时将行写入文件。

$fh = fopen('test.csv', 'w');

foreach ($collection as $product_all) {
    $sku = $product_all['sku'];
    $product_id = Mage::getModel('catalog/product')->getIdBySku($sku);
    $product    = Mage::getModel('catalog/product');
    $product ->load($product_id);   
    $name = $product['name'];

    fwrite($fh, "{$sku},{$name}\n");
}

fclose($fh);