2017-01-31 11 views
-1

以下のようなファイルがあります。 event.jsonダイナミックJSONのようなファイルをCSVファイルに変換する方法

データオブジェクトの数は、行ごとに変えることができる上記のようにファイルの

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

考えます。 私は以下のcsv出力を希望します。出力されます.csv

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

私を親切に助けてくれますか?スクリプト言語(Javascript、Pythonなど)から回答を受け入れることができます。

答えて

1

このコードはすべてのヘッダーを動的に収集し、ファイルを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 header in sorted(headers): 
     if record.has_key(header): 
      curLine.append(record[header]) 
     else: 
      curLine.append('') 
    outfile.write(",".join(curLine) + '\n') 

outfile.close() 
+0

私はおそらく、この解決策に行くだろう、今あなたはそれに未知のヘッダの処理を追加しました。あらかじめその詳細を知っておいてよかったでしょう。 – mmenschig

+0

{"eventid": "12345"、 "name": "test1"、 "age":18} {"eventid": "12346"、 "age":65} {"eventid": "12336" "name": "test3"、 "age":22、 "gender": "Male"} - 年齢を過ぎると整数が返され、うまくいかずエラーがスローされます。 – user2539119

+0

整数を受け入れることでこれを修正しましたか? – mmenschig

0
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(); 
+0

申し訳ありませんが、私はあなたが何を意味するのかについてはわかりません。動的に列見出しを取得したい。 – user2539119

+0

初期ファイルはevents.jsonのようなものになり、出力はoutput.csvになります。あなたはフォローですか?このスクリプトのevent.jsonファイルの場所はどこに渡すのですか? – user2539119

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

これが役に立ちます。

+0

こんにちは、これは1つの大きな問題(私はおそらく明確ではない)で素晴らしいです。可能なヘッダーがわからない場合はどうですか? data.jsonファイルの次の行に「アドレス」があるとしましょう。それに取り組む方法はありますか? – user2539119

+0

ハ、この練習の全体の性質が変わります。つまり、実際のヘッダー行が何であるのか、それを最後に追加する新しいエントリがわからないと言っていますか? – mmenschig

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 

たちはからcsvファイルを生成することができngCsvプラグインでAngularjsを使用して

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

を生成し、サンプルデータが含まれている次のフィルタが含まれている場合ダイナミックヘードで希望のjson rs。

Run in 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> 
 
    
 
\t <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>

関連する問題