关联多维(多维)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()

PHP Manual

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