【问题标题】:Remove out of order column data in csv when array key-value pair is missing缺少数组键值对时删除 csv 中乱序的列数据
【发布时间】:2018-02-12 23:17:35
【问题描述】:

我有一个多维数组,其中一些数组缺少在其他数组中找到的键值对。当我转换为 csv(在本例中为制表符分隔)时,行中的列单元格向左移动并替换缺少的键/值。比如这个数组:

array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

版本 1

当我使用以下代码时:

$cfilename = 'result.csv';
$data = array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

    //below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row)
{

fputcsv($fp, $row, chr(9));
}
fclose($fp);
return;

会给我这样的输出:

Volvo      |red    | 18
BMW        |blue   | 13
Saab       |11     | 
Land Rover |green  | 15

如果我使用键标签来编写标题,我可以让列正确排列。但是在这种情况下,缺少的键/值对的单元格不是空的,而是列号打印在它的位置。

第 2 版 这段代码:

$cfilename = 'result.csv';
$data = array
  (
  array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
  array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
  array("Make" => "Saab", "Quantity" => 11),
  array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
  );

//below creates csv
$fp = fopen($cfilename, 'w');
$header = false;
foreach ($data as $row)
{
    if (empty($header)) //creates header, chr(9) makes tab delimited
    {
        $header = array_keys($row);
        fputcsv($fp, $header, chr(9));
        $header = array_flip($header);
    }
    fputcsv($fp, array_merge($header, $row), chr(9)); //creates rows, chr(9) makes tab delimited
}
fclose($fp);
return;

结果如下:

Make       | Color | Quantity
-----------|-------|----
Volvo      |red    | 18
BMW        |blue   | 13
Saab       |1      | 11
Land Rover | green | 15

注意,“Saab”行中颜色下方的“1”。

让任何一个版本都能正常工作会很棒,如果是版本 1,没有标题,我总是可以将该行添加到制表符分隔的输出文件中。

【问题讨论】:

    标签: php arrays csv multidimensional-array export-to-csv


    【解决方案1】:

    如果字段不存在,为什么不直接将其设置为空字符串?

    $cfilename = 'result.csv';
    $data = array(
        array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
        array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
        array("Make" => "Saab", "Quantity" => 11),
        array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
    );
    
    //below creates csv
    $fp = fopen($cfilename, 'w');
    $header = false;
    $fields = ['Make', 'Color', 'Quantity'];
    foreach ($data as $row)
    {
        foreach($fields as $field) {
            if (!array_key_exists($field, $row) {
                $row[$field] = '';
            }
        }
        fputcsv($fp, $row, chr(9));
    }
    fclose($fp);
    return;
    

    【讨论】:

      【解决方案2】:

      值是1,因为这是颜色键的$header 数组中的值(您在合并之前翻转了它,所以现在它不是1 => "Color",而是"Color" => 1)。您可以做些什么来摆脱这种情况,将所有值设置为 NULL、空字符串或占位符,或者当没有值时您想要的任何值,使用 array_map()

      <?php
      $cfilename = 'result.csv';
      $data = array
        (
        array("Make" => "Volvo", "Color" => "red", "Quantity" => 18),
        array("Make" => "BMW", "Color" => "blue", "Quantity" => 13),
        array("Make" => "Saab", "Quantity" => 11),
        array("Make" => "Land Rover", "Color" => "green", "Quantity" => 15)
        );
      echo "<pre>";
      //below creates csv
      $fp = fopen($cfilename, 'w');
      $header = false;
      foreach ($data as $row)
      {
          if (empty($header)) //creates header, chr(9) makes tab delimited
          {
              $header = array_keys($row);
              fputcsv($fp, $header, chr(9));
              $header = array_flip($header);
              $header = array_map(function($header) { return "";}, $header);
          }
          // var_dump($header);
          fputcsv($fp, array_merge($header, $row), chr(9)); //creates rows, chr(9) makes tab delimited
      
      }
      fclose($fp);
      return;
      

      Demo (without saving to file, only printing to screen)

      【讨论】:

        猜你喜欢
        • 2013-11-02
        • 2020-02-02
        • 2021-08-13
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2021-04-29
        • 2020-06-04
        • 1970-01-01
        相关资源
        最近更新 更多