How can an associative multidimensional (multiple dimensions) PHP array get converted to downloadable CSV?

我的梦境 提交于 2020-04-30 06:24:50

问题


I have an associative multidimensional (dynamic length of dimensions) array. It originally comes from JSON data, but I understand that just makes things harder so I convert it using json_decode($original_data, true).

I'm interested to convert it to a clickable CSV file like echo '<a href="data:application/csv, ' . $data . '">Click to download</a>'.

I've tried many code variations, one of which I found online in https://coderwall.com/p/zvzwwa/array-to-comma-separated-string-in-php because its whole purpose is to "convert a multi-dimensional, associative array to CSV data". Alas, its code doesn't seem to be recursive. Unlike other functions I've tried it doesn't call itself recursively if the data isn't is_array.

Your assistance is appreciated.

Sample data:

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

        )
)

Expected output:

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

回答1:


fputcsv()

PHP Manual

Resolved on Stackoverflow




回答2:


CSV is table-like: columns in rows, seperated by a seperator.

They are unsuitable to use for dynamic length and depth datastructures.

So the short answer is: No, don't.

However, if you happen to have some knowledge about WHAT to expect, you could predefine the 'meaning' of each column and map that to certain places inside your JSON structure. But that is trickery, and only works if you know what goes where.




回答3:


@nelsonrakson's answer led me to what was a very specific answer to a very general question.

Also, that answer didn't quote the header line, used blank columns for every parent title, used strings instead of arrays and thus was left with extra commas plus unneeded calls (like $csv_data .= "" . ",";), so here it is with arrays, more proper support for parent titles and also what I wanted in the first place - an auto download of the CSV which was converted from an array:

<?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 (is_array($value))
            array2csv($value, $csv_title, $csv_data, $key);
        else {
            if (!empty($prefix))
                $key = $prefix . ' - ' . $key;
            $csv_title[] = str_wrap($key);
            $csv_data[] = str_wrap($value);
        }
    }
}
?>


来源:https://stackoverflow.com/questions/61444541/how-can-an-associative-multidimensional-multiple-dimensions-php-array-get-conv

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!