0

我有一个如下所示的文件。

{"eventid" : "12345" ,"name":"test1","age":"18"}
{"eventid" : "12346" ,"age":"65"}
{"eventid" : "12336" ,"name":"test3","age":"22","gender":"Male"}

将上述文件视为 event.json

数据对象的数量可能因行而异。我想要以下 csv 输出。它将是 output.csv

eventid,name,age,gender
12345,test1,18
12346,,65
12336,test3,22,Male

有人可以帮助我吗?我可以接受任何脚本语言(Javascript、Python 等)的答案。

4

5 回答 5

2

此代码将动态收集所有标题并将文件写入 CSV。

阅读代码中的注释以了解详细信息:

import json

# Load data from file
data = '''{"eventid" : "12345" ,"name":"test1","age":"18"}
{"eventid" : "12346" ,"age":"65"}
{"eventid" : "12336" ,"name":"test3","age":"22","gender":"Male"}'''

# Store records for later use
records = [];

# Keep track of headers in a set
headers = set([]);

for line in data.split("\n"):
    line = line.strip();

    # Parse each line as JSON
    parsedJson = json.loads(line)

    records.append(parsedJson)

    # Make sure all found headers are kept in the headers set
    for header in parsedJson.keys():
        headers.add(header)

# You only know what headers were there once you have read all the JSON once.

#Now we have all the information we need, like what all possible headers are.

outfile = open('output_json_to_csv.csv','w')

# write headers to the file in order
outfile.write(",".join(sorted(headers)) + '\n')

for record in records:
    # write each record based on available fields
    curLine = []
    # For each header in alphabetical order
    for header in sorted(headers):
        # If that record has the field
        if record.has_key(header):
            # Then write that value to the line
            curLine.append(record[header])
        else:
            # Otherwise put an empty value as a placeholder
            curLine.append('')
    # Write the line to file
    outfile.write(",".join(curLine) + '\n')

outfile.close()
于 2017-01-31T21:08:41.460 回答
2

这是使用jq的解决方案。

如果filter.jq包含以下过滤器

  (reduce (.[]|keys_unsorted[]) as $k ({};.[$k]="")) as $o   # object with all keys
| ($o  | keys_unsorted), (.[] | $o * . | [.[]])              # generate header and data
| join(",")                                                  # convert to csv

然后data.json包含样本数据

$ jq -Mrs -f filter.jq data.json

生产

eventid,name,age,gender
12345,test1,18,
12346,,65,
12336,test3,22,Male
于 2017-09-03T21:57:02.270 回答
0

这是一个 Python 解决方案(应该适用于 Python 2 和 3)。我对代码并不感到自豪,因为可能有更好的方法来做到这一点(使用 csv 模块),但这会给你想要的输出。

我冒昧地命名了您的 JSON 数据data.json,并命名了输出 csv 文件output.csv

import json

header = ['eventid', 'name', 'age', 'gender']

with open('data.json', 'r') as infile, \
     open('outfile.csv', 'w+') as outfile:

    # Writes header row
    outfile.write(','.join(header))
    outfile.write('\n')

    for row in infile:
        line = ['', '', '', ''] # I'm sure there's a better way
        datarow = json.loads(row)

        for key in datarow:
            line[header.index(key)] = datarow[key]

        outfile.write(','.join(line))
        outfile.write('\n')

希望这可以帮助。

于 2017-01-31T20:52:19.670 回答
0

使用带有 ngCsv 插件的 Angularjs,我们可以从所需的带有动态标题的 json 生成 csv 文件。

在 plunkr 中运行

// Code goes here

 var myapp = angular.module('myapp', ["ngSanitize", "ngCsv"]);

 myapp.controller('myctrl', function($scope) {
   $scope.filename = "test";
   $scope.getArray = [{
     label: 'Apple',
     value: 2,
     x:1,
   }, {
     label: 'Pear',
     value: 4,
     x:38
   }, {
     label: 'Watermelon',
     value: 4,
     x:38
   }];


   $scope.getHeader = function() {
    var vals = [];
    for( var key in $scope.getArray ) {
    for(var k in $scope.getArray[key]){
      vals.push(k);
     }
     break;
    }
    return vals;
    
   };

 });
<!DOCTYPE html>
<html>
  <head>
    <link href="https://netdna.bootstrapcdn.com/bootstrap/3.0.0/css/bootstrap.min.css" rel="stylesheet">

    <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular.min.js"></script>

   <script src="https://ajax.googleapis.com/ajax/libs/angularjs/1.4.7/angular-sanitize.min.js"></script>
   
	<script src="https://cdnjs.cloudflare.com/ajax/libs/ng-csv/0.3.6/ng-csv.min.js"></script>
   

  </head>


  <body>

    <div ng-app="myapp">

      <div class="container" ng-controller="myctrl">

        <div class="page-header">

          <h1>ngCsv <small>example</small></h1>

        </div>
       
        

        <button class="btn btn-default" ng-csv="getArray" csv-header="getHeader()" filename="{{ filename }}.csv" field-separator="," decimal-separator=".">Export to CSV with header</button>

       
      </div>
    </div>
  </body>
</html>

于 2018-01-08T07:58:48.730 回答
-1
var arr = $.map(obj, function(el) { return el });
var content = "";
for(var element in arr){
    content += element + ",";
}

var filePath = "someFile.csv";
var fso = new ActiveXObject("Scripting.FileSystemObject");
var fh = fso.OpenTextFile(filePath, 8, false, 0);
fh.WriteLine(content);
fh.Close();
于 2017-01-31T20:25:01.410 回答