【问题标题】:Convert array into csv将数组转换为csv
【发布时间】:2011-04-25 10:08:35
【问题描述】:

如何将数组转换为 CSV 文件?

这是我的数组:

stdClass Object
(

    [OrderList_RetrieveByContactResult] => stdClass Object
        (
            [OrderDetails] => stdClass Object
                (
                    [entityId] => 1025298
                    [orderId] => 10952
                    [orderName] => testing
                    [statusTypeId] => 4652
                    [countryCode] => AU
                    [orderType] => 1
                    [invoiceNumber] => 0
                    [invoiceDate] => 0001-01-01T00:00:00
                    [userID_AssignedTo] => 11711
                    [shippingAmount] => 8.95
                    [shippingTaxRate] => 0
                    [shippingAttention] => 
                    [shippingInstructions] => 
                    [shippingOptionId] => 50161
                    [discountCodeId] => 0
                    [discountRate] => 0
                    [totalOrderAmount] => 408.45
                    [directDebitTypeId] => 0
                    [directDebitDays] => 0
                    [isRecur] => 
                    [nextInvoiceDate] => 0001-01-01T00:00:00
                    [endRecurDate] => 0001-01-01T00:00:00
                    [cycleTypeID] => 1
                    [createDate] => 2010-10-08T18:40:00
                    [lastUpdateDate] => 2010-10-08T18:40:00
                    [deleted] => 
                    [products] => stdClass Object
                        (
                            [Product] => stdClass Object
                                (
                                    [productId] => 674975
                                    [productCode] => 
                                    [productDescription] => 
                                    [units] => 10
                                    [unitPrice] => 39.95
                                    [unitTaxRate] => 0
                                    [totalProductPrice] => 399.5
                                    [productName] => Acne Clearing Gel
                                )

                        )

                    [addresses] => stdClass Object
                        (
                            [Address] => stdClass Object
                                (
                                    [addressTypeID] => 8
                                    [addressLine1] => Cebu City
                                    [city] => Cebu
                                    [zipcode] => 6000
                                    [state] => 
                                    [countryCode] => PH
                                )

                        )

                )

        )

)

【问题讨论】:

  • 您可能想用您的代码编写的任何语言来标记这个问题。这将帮助您获得更多关注您的问题的眼球。 :)
  • 我认为没有办法在 CSV 中呈现多维性,是吗?
  • 另见this solution,它将fputcsv()ob_start(); $df = fopen("php://output", 'w'); fclose($df); return ob_get_clean();结合使用。

标签: php arrays csv


【解决方案1】:

我为此使用了以下功能;它改编自 fputscsv cmets 中的一个 man 条目。而且您可能想要展平该阵列;不知道如果你传入一个多维的会发生什么。

/**
  * Formats a line (passed as a fields  array) as CSV and returns the CSV as a string.
  * Adapted from http://us3.php.net/manual/en/function.fputcsv.php#87120
  */
function arrayToCsv( array &$fields, $delimiter = ';', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
    $delimiter_esc = preg_quote($delimiter, '/');
    $enclosure_esc = preg_quote($enclosure, '/');

    $output = array();
    foreach ( $fields as $field ) {
        if ($field === null && $nullToMysqlNull) {
            $output[] = 'NULL';
            continue;
        }

        // Enclose fields containing $delimiter, $enclosure or whitespace
        if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
            $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure;
        }
        else {
            $output[] = $field;
        }
    }

    return implode( $delimiter, $output );
}

【讨论】:

  • 嗨,保罗,谢谢它对我帮助很大。你是最好的! :D
  • 嗨,这对我有用。但我有一个问题,如何在 1 行之后创建一个新行?我在我的 for 循环中添加了一个计数器,如果它是第一个索引的结尾,我会追加一个新行,如 $output[$i] .= "\r\n";它创建了一个新行,但也在接下来的行中添加了一个新单元格。
  • 有一种极端情况,如果您的$fields 数组中的最后一个值为空字符串,则将其丢弃。因此,如果您的数组有 3 个元素长并且最后一个元素是一个空字符串,那么您将在空字符串之前获得由 2 个分隔符分隔的值,而不是表示最后一个值为空所需的 3 个值。
【解决方案2】:

我的解决方案要求数组的格式与问题中提供的不同:

<?
    $data = array(
        array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
        array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
        array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
    );
?>

我们定义我们的函数:

<?
    function outputCSV($data) {
        $outputBuffer = fopen("php://output", 'w');
        foreach($data as $val) {
            fputcsv($outputBuffer, $val);
        }
        fclose($outputBuffer);
    }
?>

然后我们将数据输出为 CSV:

<?
    $filename = "example";

    header("Content-type: text/csv");
    header("Content-Disposition: attachment; filename={$filename}.csv");
    header("Pragma: no-cache");
    header("Expires: 0");

    outputCSV($data);
?>

我已经在几个项目中使用了它,并且效果很好。我应该注意到outputCSV代码比我聪明,所以我确定我不是原作者。不幸的是,我不知道我是从哪里得到它的,所以我不能把它归功于谁。

【讨论】:

    【解决方案3】:

    当您想在模板中创建和回显 CSV 时,kingjeffrey 对上述解决方案进行了轻微调整(即,大多数框架将启用输出缓冲,并且您需要在控制器中设置标头等。)

    // Create Some data
    <?php
        $data = array(
            array( 'row_1_col_1', 'row_1_col_2', 'row_1_col_3' ),
            array( 'row_2_col_1', 'row_2_col_2', 'row_2_col_3' ),
            array( 'row_3_col_1', 'row_3_col_2', 'row_3_col_3' ),
        );
    
    
    // Create a stream opening it with read / write mode
    $stream = fopen('data://text/plain,' . "", 'w+');
    
    // Iterate over the data, writting each line to the text stream
    foreach ($data as $val) {
        fputcsv($stream, $val);
    }
    
    // Rewind the stream
    rewind($stream);
    
    // You can now echo it's content
    echo stream_get_contents($stream);
    
    // Close the stream 
    fclose($stream);
    

    感谢上面的 Kingjeffrey 以及 blog post,我在其中找到了有关创建文本流的信息。

    【讨论】:

    • 此解决方案在不允许创建文件权限的情况下很有用
    【解决方案4】:
    function array_2_csv($array) {
        $csv = array();
        foreach ($array as $item) {
            if (is_array($item)) {
                $csv[] = array_2_csv($item);
            } else {
                $csv[] = $item;
            }
        }
        return implode(',', $csv);
    } 
    
    $csv_data = array_2_csv($array);
    
    echo "<pre>";
    print_r($csv_data);
    echo '</pre>'   ; 
    

    【讨论】:

    • 您好 Paulrajj,非常感谢。你真的帮助我的问题。你真棒伙计! :D
    【解决方案5】:

    Paul 接受的回答很棒。我对此做了一个小的扩展,如果你有一个像这样的多维数组(这很常见),这非常有用:

    Array
    (
        [0] => Array
            (
                [a] => "a"
                [b] => "b"
            )
    
        [1] => Array
            (
                [a] => "a2"
                [b] => "b2"
            )
    
        [2] => Array
            (
                [a] => "a3"
                [b] => "b3"
            )
    
        [3] => Array
            (
                [a] => "a4"
                [b] => "b4"
            )
    
        [4] => Array
            (
                [a] => "a5"
                [b] => "b5"
            )
    
    )
    

    所以我只是从上面取了 Paul 的函数:

    /**
      * Formats a line (passed as a fields  array) as CSV and returns the CSV as a string.
      * Adapted from http://us3.php.net/manual/en/function.fputcsv.php#87120
      */
    function arrayToCsv( array &$fields, $delimiter = ';', $enclosure = '"', $encloseAll = false, $nullToMysqlNull = false ) {
        $delimiter_esc = preg_quote($delimiter, '/');
        $enclosure_esc = preg_quote($enclosure, '/');
    
        $output = array();
        foreach ( $fields as $field ) {
            if ($field === null && $nullToMysqlNull) {
                $output[] = 'NULL';
                continue;
            }
    
            // Enclose fields containing $delimiter, $enclosure or whitespace
            if ( $encloseAll || preg_match( "/(?:${delimiter_esc}|${enclosure_esc}|\s)/", $field ) ) {
                $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure;
            }
            else {
                $output[] = $field;
            }
        }
    
        return implode( $delimiter, $output );
    }
    

    并添加了这个:

    function a2c($array, $glue = "\n")
    {
        $ret = [];
        foreach ($array as $item) {
            $ret[] = arrayToCsv($item);
        }
        return implode($glue, $ret);
    }
    

    所以你可以打电话:

    $csv = a2c($array);
    

    如果你想要一个特殊的行尾,你可以使用可选参数“glue”。

    【讨论】:

      【解决方案6】:

      根据接受的答案添加一些改进。

      1. PHP 7.0 严格输入
      2. PHP 7.0 类型声明和返回类型声明
      3. 附件\r、\n、\t
      4. 即使 $encloseAll 为 TRUE,也不要包含空字符串
      /**
        * Formats a line (passed as a fields array) as CSV and returns the CSV as a string.
        * Adapted from https://www.php.net/manual/en/function.fputcsv.php#87120
        */
      function arrayToCsv(array $fields, string $delimiter = ';', string $enclosure = '"', bool $encloseAll = false, bool $nullToMysqlNull = false): string {
      
          $delimiter_esc = preg_quote($delimiter, '/');
          $enclosure_esc = preg_quote($enclosure, '/');
      
          $output = [];
          foreach ($fields as $field) {
              if ($field === null && $nullToMysqlNull) {
                  $output[] = 'NULL';
                  continue;
              }
              // Enclose fields containing $delimiter, $enclosure or whitespace, newline
              $field = strval($field);
              if (strlen($field) && ($encloseAll || preg_match("/(?:${delimiter_esc}|${enclosure_esc}|\s|\r|\n|\t)/", $field))) {
                  $output[] = $enclosure . str_replace($enclosure, $enclosure . $enclosure, $field) . $enclosure;
              } else {
                  $output[] = $field;
              }
          }
      
          return implode($delimiter, $output);
      
      }
      

      【讨论】:

        【解决方案7】:

        好吧,也许 4 年后有点晚了哈哈……但我一直在寻找对 CSV 执行 OBJECT 的解决方案,但是这里的大多数解决方案实际上是针对 ARRAY 到 CSV 的……

        经过一番修改,这是我将对象转换为 CSV 的解决方案,我认为它非常简洁。希望这对其他人有帮助。

        $resp = array();
        foreach ($entries as $entry) {
            $row = array();
            foreach ($entry as $key => $value) {
                array_push($row, $value);
            }
            array_push($resp, implode(',', $row));
        }
        echo implode(PHP_EOL, $resp);
        

        请注意,要使$key =&gt; $value 起作用,您的object 的属性必须是公开的,不会获取私有的。

        最终的结果是你会得到这样的结果:

        blah,blah,blah
        blah,blah,blah
        

        【讨论】:

          猜你喜欢
          • 2011-11-22
          • 2022-01-17
          • 2021-10-10
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2015-03-05
          相关资源
          最近更新 更多