将数组转换为csv

时间:2010-10-14 13:32:25

标签: php arrays csv

如何将数组转换为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
                                )

                        )

                )

        )

)

7 个答案:

答案 0 :(得分:74)

我正在使用以下功能;它是来自fputscsv评论中的一个人条目的改编。你可能想要压扁那个阵列;不确定如果传入多维文件会发生什么。

/**
  * 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 );
}

答案 1 :(得分:42)

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

<?
    $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代码比我更聪明,所以我相信我不是原作者。不幸的是,我已经忘记了我在哪里得到它,所以我不能把它归功于它应该到期的人。

答案 2 :(得分:15)

当你想在一个模板中创建并回显CSV时,对于上面的解决方案略有改进(即大多数框架都会启用输出缓冲,你需要在控制器中设置标题等。)

// 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

答案 3 :(得分:14)

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>'   ; 

答案 4 :(得分:1)

保罗接受的答案很好。我对此做了一个小的扩展,如果您有一个这样的多维数组(这很常见),这将非常有用:

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”。

答案 5 :(得分:0)

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

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

}

答案 6 :(得分:-2)

好吧也许4年后有点晚了哈哈...但是我一直在寻找OBJECT到CSV的解决方案,但是这里的大多数解决方案实际上是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 => $value生效,您的object属性必须是公开的,私有属性不会被提取。

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

blah,blah,blah
blah,blah,blah