php 将数组转换为 csv

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/3933668/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-25 11:30:02  来源:igfitidea点击:

Convert array into csv

phparrayscsv

提问by rayss

How to convert an array into a CSV file?

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

This is my array:

这是我的数组:

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
                                )

                        )

                )

        )

)

回答by Paul

I'm using the following function for that; it's an adaptation from one of the man entries in the fputscsv comments. And you'll probably want to flatten that array; not sure what happens if you pass in a multi-dimensional one.

我为此使用了以下功能;它改编自 fputscsv 评论中的 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 );
}

回答by kingjeffrey

My solution requires the array be formatted differently than provided in the question:

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

<?
    $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' ),
    );
?>

We define our function:

我们定义我们的函数:

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

Then we output our data as a CSV:

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

<?
    $filename = "example";

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

    outputCSV($data);
?>

I have used this with several projects, and it works well. I should note that the outputCSVcode is more clever than I am, so I am sure I am not the original author. Unfortunately I have lost track of where I got it, so I can't give the credit to whom it is due.

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

回答by Ben Waine

A slight adaptation to the solution above by kingjeffrey for when you want to create and echo the CSV within a template (Ie - most frameworks will have output buffering enabled and you are required to set headers etc in controllers.)

当您想在模板中创建和回显 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);

Credit to Kingjeffrey above and also to this blog postwhere I found the information about creating text streams.

感谢上面的 Kingjeffrey 以及这篇博客文章,我在其中找到了有关创建文本流的信息。

回答by Paulraj

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

回答by Marco

The accepted answer from Paul is great. I've made a small extension to this which is very useful if you have an multidimensional array like this (which is quite common):

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

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

)

So I just took Paul's function from above:

所以我只是从上面取了保罗的功能:

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

And added this:

并补充说:

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

So you can just call:

所以你可以打电话:

$csv = a2c($array);

If you want a special line ending you can use the optional parameter "glue" for this.

如果您想要一个特殊的行结束,您可以为此使用可选参数“glue”。

回答by Dragon

Add some improvements based on accepted answer.

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

  1. PHP 7.0 Strict typing
  2. PHP 7.0 Type declaration and Return type declaration
  3. Enclosure \r, \n, \t
  4. Don't enclosure empty string even $encloseAll is TRUE
  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);

}

回答by codenamezero

Well maybe a little late after 4 years haha... but I was looking for solution to do OBJECT to CSV, however most solutions here is actually for ARRAY to CSV...

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

After some tinkering, here is my solution to convert object into CSV, I think is pretty neat. Hope this would help someone else.

经过一番修修补补,这是我将对象转换为 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);

Note that for the $key => $valueto work, your object's attributes must be public, the private ones will not get fetched.

请注意,$key => $value要工作,您object的属性必须是公共的,私有的将不会被获取。

The end result is that you get something like this:

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

blah,blah,blah
blah,blah,blah