嵌套JSON到CSV格式Node.js

时间:2016-02-06 18:56:48

标签: javascript json node.js csv

我是编程新手,正在开发一个项目,该项目使用node.js从API接收嵌套的JSON响应。我希望找到一种简单的方法将此JSON转换为CSV以供导出。我已经搜索了一下尝试了jsonexport和nestedcsv2json软件包,但是我无法将格式设置得恰到好处,并且无法通过我的JSON响应进行迭代。

基本上JSON响应如下:

{ '2016-01-31': { chats: 0, missed_chats: 5 },
'2016-02-01': { chats: 60, missed_chats: 7 },
'2016-02-02': { chats: 56, missed_chats: 1 },
'2016-02-03': { chats: 46, missed_chats: 0 },
'2016-02-04': { chats: 63, missed_chats: 2 },
'2016-02-05': { chats: 59, missed_chats: 4 },
'2016-02-06': { chats: 0, missed_chats: 1 } }

我遇到的问题是,这个问题的大小可能会因用户输入的日期范围而有所不同。所以我需要遍历返回的日期,然后提取嵌套的JSON。它可以是一个日期或100个日期。

我希望制作一个包含我可以导出的标题的CSV格式:

   Date         Chats    Missed Chats
2016-02-02        60            7

这应该快速而简单,但我很难做到这一点。任何提示或帮助非常感谢。谢谢!

4 个答案:

答案 0 :(得分:1)

这将输出以分号分隔的csv-string。编辑分隔符(例如将其替换为选项卡\t)以满足您的需求:

var json = { '2016-01-31': { chats: 0, missed_chats: 5 },
'2016-02-01': { chats: 60, missed_chats: 7 },
'2016-02-02': { chats: 56, missed_chats: 1 },
'2016-02-03': { chats: 46, missed_chats: 0 },
'2016-02-04': { chats: 63, missed_chats: 2 },
'2016-02-05': { chats: 59, missed_chats: 4 },
'2016-02-06': { chats: 0, missed_chats: 1 } };

var headers = 'Date;Chats;Missed chats';

var csv = headers + '\r\n';
for(key in json){
    csv += key + ';' + json[key].chats + ';' + json[key].missed_chats + '\r\n'
}
console.log(csv)

输出结果为:

Date;Chats;Missed chats
2016-01-31;0;5
2016-02-01;60;7
2016-02-02;56;1
2016-02-03;46;0
2016-02-04;63;2
2016-02-05;59;4
2016-02-06;0;1

您可以在此处找到一个有效的示例:https://jsfiddle.net/owd8zsa0/

答案 1 :(得分:0)

此答案将自动获取标题(第一行),并将其添加到CSV。

var input={ '2016-01-31': { chats: 0, missed_chats: 5 },
'2016-02-01': { chats: 60, missed_chats: 7 },
'2016-02-02': { chats: 56, missed_chats: 1 },
'2016-02-03': { chats: 46, missed_chats: 0 },
'2016-02-04': { chats: 63, missed_chats: 2 },
'2016-02-05': { chats: 59, missed_chats: 4 },
'2016-02-06': { chats: 0, missed_chats: 1 } }

function json2csv(input){
    var result=''
    var firstLine=true
    for (var i in input){
        if(firstLine){
            firstLine=false
            result='id\t'
            for (var j in input[i]){
                result+=j +';'
            }
            result+='\n'
        }
        else{
            result+=i+'\t'
            for (var j in input[i]){
                result+=input[i][j] +';'
            }
            result+='\n'
        }

    }
    return result
}

console.log(json2csv(input));

结果:

id;chats;missed_chats;
2016-02-01;60;7;
2016-02-02;56;1;
2016-02-03;46;0;
2016-02-04;63;2;
2016-02-05;59;4;
2016-02-06;0;1;

答案 2 :(得分:0)

使用lodashcsv包:

var csv = require('csv');
var _ = require('lodash');

var obj = {
    '2016-01-31': { chats: 0, missed_chats: 5 },
    '2016-02-01': { chats: 60, missed_chats: 7 },
    '2016-02-02': { chats: 56, missed_chats: 1 },
    '2016-02-03': { chats: 46, missed_chats: 0 },
    '2016-02-04': { chats: 63, missed_chats: 2 },
    '2016-02-05': { chats: 59, missed_chats: 4 },
    '2016-02-06': { chats: 0, missed_chats: 1 }
};

// flatten obj to have an array of object like
// { date: '2016-01-31', chats: 0, missed_chats: 5 }
obj = _.map(obj, function (value, key) {
    return _.merge({ date: key }, value);
})

csv.stringify(obj, { header: true }, function(err, result) {
    console.log(result);
});

/* output:
date,chats,missed_chats
2016-01-31,0,5
2016-02-01,60,7
2016-02-02,56,1
2016-02-03,46,0
2016-02-04,63,2
2016-02-05,59,4
2016-02-06,0,1
*/

答案 3 :(得分:0)

问题中显示的“JSON响应”在技术上并不是有效的JSON,因此这个答案取决于JSON感知工具(jq),第一个任务是将“JSON响应”转换为有效JSON。这可以使用json5any-json完成(例如)。

假设“JSON响应”位于名为response.txt的文件中,我们可以按照以下步骤进行操作,其中初始$表示类似bash的shell:

$ any-json -format json5 < response.txt | jq -r '. as $in
  | keys[]
  | [.] + ($in[.] | [.chats, .missed_chats ]) | @csv'

这会产生以下输出:

"2016-01-31",0,5
"2016-02-01",60,7
"2016-02-02",56,1
"2016-02-03",46,0
"2016-02-04",63,2
"2016-02-05",59,4
"2016-02-06",0,1

此输出是有效的CSV(使用逗号作为分隔符),但如果您想要TSV(使用制表符作为分隔符)或者如果您不想要双引号,只需将@csv替换为@tsv即可生成以下输出:

2016-01-31  0   5
2016-02-01  60  7
2016-02-02  56  1
2016-02-03  46  0
2016-02-04  63  2
2016-02-05  59  4
2016-02-06  0   1

在任何一种情况下添加一行标题(使用jq或其他方式)都是微不足道的,因此您可以选择如何处理它。

注意:如果您使用json5,您将分两步进行。