【问题标题】:Nested JSON to CSV format Node.js嵌套 JSON 到 CSV 格式 Node.js
【发布时间】:2016-05-16 16:01:24
【问题描述】:

我是编程新手,正在开发一个项目,该项目使用 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

这应该是快速和简单的,但我正在努力做到这一点。非常感谢任何提示或帮助。谢谢!

【问题讨论】:

    标签: javascript json node.js csv


    【解决方案1】:

    这会输出一个分号分隔的 csv 字符串。编辑分隔符(例如将其替换为标签\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/

    【讨论】:

    • 谢谢!这非常适合我的需求。简单有效。
    【解决方案2】:

    这个答案,将自动获取标题(第一行),并将其添加到 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;
    

    【讨论】:

      【解决方案3】:

      使用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
      */
      

      【讨论】:

        【解决方案4】:

        问题中显示的“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,你将分两步进行。

        【讨论】:

          猜你喜欢
          • 2020-07-06
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2023-02-14
          • 2016-05-14
          • 1970-01-01
          • 2015-02-07
          相关资源
          最近更新 更多