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
Convert array into csv
提问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 outputCSV
code 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.
根据接受的答案添加一些改进。
- PHP 7.0 Strict typing
- PHP 7.0 Type declaration and Return type declaration
- Enclosure \r, \n, \t
- Don't enclosure empty string even $encloseAll is TRUE
- PHP 7.0 严格输入
- PHP 7.0 类型声明和返回类型声明
- 外壳\r、\n、\t
- 即使 $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 => $value
to 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