关联多维(多维)PHP 数组如何转换为可下载的 CSV?
How can an associative multidimensional (multiple dimensions) PHP array get converted to downloadable CSV?
我有一个关联的多维(维度的动态长度)数组。它最初来自 JSON 数据,但我知道这只会让事情变得更难,所以我使用 json_decode($original_data, true)
.
转换它
我有兴趣将其转换为可点击的 CSV 文件,例如 echo '<a href="data:application/csv, ' . $data . '">Click to download</a>'
。
我尝试了很多代码变体,其中之一是我在 https://coderwall.com/p/zvzwwa/array-to-comma-separated-string-in-php 中在线找到的,因为它的全部目的是 "convert a multi-dimensional, associative array to CSV data"。 las,它的代码似乎不是递归的。与我尝试过的其他函数不同,如果数据不是 is_array
.
,它不会递归调用自身
感谢您的帮助。
示例数据:
$array = array(
'name' => 'Test',
'average' => 1,
'fp' => '',
'dates' => array(
'isScheduled' => '',
'startDate' => 1587418137,
'endDate' => 1587418137,
'pViewValue' => array(
'startDate' => '2020-04-20T18:28:57.000Z',
'endDate' => '2020-04-20T18:28:57.000Z',
)
)
);
echo '<pre>' . print_r($array, true) . '</pre>';
Array
(
[name] => Test
[average] => 1
[fp] =>
[dates] => Array
(
[isScheduled] =>
[startDate] => 1587418137
[endDate] => 1587418137
[pViewValue] => Array
(
[startDate] => 2020-04-20T18:28:57.000Z
[endDate] => 2020-04-20T18:28:57.000Z
)
)
)
预期输出:
name average fp dates-isScheduled date-StartDate date-endDate date-pViewValue-startDate date-pViewValue-endDate
test 1 1587418137 1587418137 2020-04-20T18:28:57.000Z 2020-04-20T18:28:57.000Z
CSV 类似于 table:列在行中,由分隔符分隔。
它们不适合table用于动态长度和深度数据结构。
所以简短的回答是:不,不要。
但是,如果您恰好对期望的内容有所了解,则可以预定义每列的 'meaning' 并将其映射到 CSV 结构中的特定位置。
但那是骗人的,只有当你知道什么去哪里时才有效。
fputcsv()
Resolved on Whosebug
@nelsonrakson 的回答让我想到了 a very specific answer 一个非常笼统的问题。
此外,该答案没有引用 header 行,每个 parent 标题都使用空白列,使用字符串而不是数组,因此留下了额外的逗号和不需要的调用(例如$csv_data .= "" . ",";
),所以这里是数组,更适当地支持 parent 标题以及我首先想要的 - 从数组转换的 CSV 的自动下载:
更新 1:还添加了对 [something] => array()
等空数组的支持。
更新 2:还添加了对空值、布尔值和换行符的支持
<?php
$array = array(
'name of' => 'Test',
'average' => 1,
'fp' => '',
'dates' => array(
'isScheduled' => '',
'startDate' => 1587418137,
'endDate' => 1587418137,
'pViewValue' => array(
'startDate' => '2020-04-20T18:28:57.000Z',
'endDate' => '2020-04-20T18:28:57.000Z',
)
)
);
echo '<pre>' . print_r($array, true) . '</pre>';
$csv_title = array();
$csv_data = array();
array2csv($array, $csv_title, $csv_data);
$csv_title = implode(",", $csv_title);
$csv_data = implode(",", $csv_data);
echo $csv_title . "\n<br />" . $csv_data . "\n\n" . '
<script>
thevalue = \'' . $csv_title . "\n\\n" . $csv_data . '\'
var blob = new Blob([thevalue], {type: \'attachment/csv\'});
var blobUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
with (a) {
// href="data:attachment/" + extension + ";charset=utf-8;base64," + utf8_to_b64(thevalue);
// href="data:text/" + save as + ";charset=\'utf-8\'," + thevalue;
href=blobUrl
download = "export.csv";
}
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
</script>
';
function str_wrap($string = '', $char = '"') {
return str_pad($string, strlen($string) + 2, $char, STR_PAD_BOTH);
}
function array2csv($array, &$csv_title, &$csv_data, $prefix = '') {
foreach($array as $key => $value) {
if (!empty($prefix) || strlen($prefix) > 0)
$key = $prefix . ' - ' . $key;
if (is_array($value) && !empty($value))
array2csv($value, $csv_title, $csv_data, $key);
else {
$csv_title[] = $key; //str_wrap($key);
if (is_null($value))
$csv_data[] = 'NULL';
else if ($value === false)
$csv_data[] = 0;
else
$csv_data[] = str_replace("\n", "\n", $value);
// $csv_data[] = str_wrap(addcslashes(str_replace("\n", "\n", $value, ','));
}
}
}
?>
我有一个关联的多维(维度的动态长度)数组。它最初来自 JSON 数据,但我知道这只会让事情变得更难,所以我使用 json_decode($original_data, true)
.
我有兴趣将其转换为可点击的 CSV 文件,例如 echo '<a href="data:application/csv, ' . $data . '">Click to download</a>'
。
我尝试了很多代码变体,其中之一是我在 https://coderwall.com/p/zvzwwa/array-to-comma-separated-string-in-php 中在线找到的,因为它的全部目的是 "convert a multi-dimensional, associative array to CSV data"。 las,它的代码似乎不是递归的。与我尝试过的其他函数不同,如果数据不是 is_array
.
感谢您的帮助。
示例数据:
$array = array(
'name' => 'Test',
'average' => 1,
'fp' => '',
'dates' => array(
'isScheduled' => '',
'startDate' => 1587418137,
'endDate' => 1587418137,
'pViewValue' => array(
'startDate' => '2020-04-20T18:28:57.000Z',
'endDate' => '2020-04-20T18:28:57.000Z',
)
)
);
echo '<pre>' . print_r($array, true) . '</pre>';
Array
(
[name] => Test
[average] => 1
[fp] =>
[dates] => Array
(
[isScheduled] =>
[startDate] => 1587418137
[endDate] => 1587418137
[pViewValue] => Array
(
[startDate] => 2020-04-20T18:28:57.000Z
[endDate] => 2020-04-20T18:28:57.000Z
)
)
)
预期输出:
name average fp dates-isScheduled date-StartDate date-endDate date-pViewValue-startDate date-pViewValue-endDate
test 1 1587418137 1587418137 2020-04-20T18:28:57.000Z 2020-04-20T18:28:57.000Z
CSV 类似于 table:列在行中,由分隔符分隔。
它们不适合table用于动态长度和深度数据结构。
所以简短的回答是:不,不要。
但是,如果您恰好对期望的内容有所了解,则可以预定义每列的 'meaning' 并将其映射到 CSV 结构中的特定位置。 但那是骗人的,只有当你知道什么去哪里时才有效。
fputcsv()
Resolved on Whosebug
@nelsonrakson 的回答让我想到了 a very specific answer 一个非常笼统的问题。
此外,该答案没有引用 header 行,每个 parent 标题都使用空白列,使用字符串而不是数组,因此留下了额外的逗号和不需要的调用(例如$csv_data .= "" . ",";
),所以这里是数组,更适当地支持 parent 标题以及我首先想要的 - 从数组转换的 CSV 的自动下载:
更新 1:还添加了对 [something] => array()
等空数组的支持。
更新 2:还添加了对空值、布尔值和换行符的支持
<?php
$array = array(
'name of' => 'Test',
'average' => 1,
'fp' => '',
'dates' => array(
'isScheduled' => '',
'startDate' => 1587418137,
'endDate' => 1587418137,
'pViewValue' => array(
'startDate' => '2020-04-20T18:28:57.000Z',
'endDate' => '2020-04-20T18:28:57.000Z',
)
)
);
echo '<pre>' . print_r($array, true) . '</pre>';
$csv_title = array();
$csv_data = array();
array2csv($array, $csv_title, $csv_data);
$csv_title = implode(",", $csv_title);
$csv_data = implode(",", $csv_data);
echo $csv_title . "\n<br />" . $csv_data . "\n\n" . '
<script>
thevalue = \'' . $csv_title . "\n\\n" . $csv_data . '\'
var blob = new Blob([thevalue], {type: \'attachment/csv\'});
var blobUrl = URL.createObjectURL(blob);
var a = document.createElement("a");
with (a) {
// href="data:attachment/" + extension + ";charset=utf-8;base64," + utf8_to_b64(thevalue);
// href="data:text/" + save as + ";charset=\'utf-8\'," + thevalue;
href=blobUrl
download = "export.csv";
}
document.body.appendChild(a);
a.click();
document.body.removeChild(a);
</script>
';
function str_wrap($string = '', $char = '"') {
return str_pad($string, strlen($string) + 2, $char, STR_PAD_BOTH);
}
function array2csv($array, &$csv_title, &$csv_data, $prefix = '') {
foreach($array as $key => $value) {
if (!empty($prefix) || strlen($prefix) > 0)
$key = $prefix . ' - ' . $key;
if (is_array($value) && !empty($value))
array2csv($value, $csv_title, $csv_data, $key);
else {
$csv_title[] = $key; //str_wrap($key);
if (is_null($value))
$csv_data[] = 'NULL';
else if ($value === false)
$csv_data[] = 0;
else
$csv_data[] = str_replace("\n", "\n", $value);
// $csv_data[] = str_wrap(addcslashes(str_replace("\n", "\n", $value, ','));
}
}
}
?>