2011-10-21 14 views
12

मैं रूबी का उपयोग कर .csv फ़ाइल में .json फ़ाइल को कनवर्ट करना चाहता हूं। खुशी मुझे ऐसा करने में मदद करती है।रूबी में .json से .csv कनवर्ट करें

यह भी प्राप्त करने के लिए किसी भी उपकरण का प्रस्ताव है।

+0

देखो: http://stackoverflow.com/questions/5357711/csv-to-json-ruby-script – WarHog

+0

आप JSON डेटा के लिए एक उदाहरण है? JSON स्वयं में बहुआयामी हो सकता है, और सीएसवी 2-आयामी है। – mliebelt

उत्तर

21

कुछ इस तरह का प्रयास करें:

require 'csv' 
require 'json' 

csv_string = CSV.generate do |csv| 
    JSON.parse(File.open("foo.json").read).each do |hash| 
    csv << hash.values 
    end 
end 

puts csv_string 
+1

अच्छा और सरल। ध्यान रखें कि यह खाते में घोंसला नहीं लेता है और मानता है कि सूची में सभी ऑब्जेक्ट समान हैं। – SirLenz0rlot

8

वास्तव में फ़ाइल पर लिखने में ...

require 'csv' 
require 'json' 

CSV.open("your_csv.csv", "w") do |csv| #open new file for write 
    JSON.parse(File.open("your_json.json").read).each do |hash| #open json to parse 
    csv << hash.values #write value to file 
    end 
end 
5

मुझे लगता है कि जिस तरह से easies माणिक में सीएसवी करने के लिए JSON कन्वर्ट करने के लिए कर रहा है json2csv माणिक रत्न का उपयोग कर।

पीएस: मैं पक्षपातपूर्ण हो सकता हूं क्योंकि मैं इसके लेखक हूं।

json2csv github repo

आदेश

json2csv convert data/sample.json 

इनपुट फ़ाइल

चल रहा है इस विशेष मामले में यह json निम्नलिखित कनवर्ट होने की:

cat data/sample.json 

{ 
"12345": { 
    "Firstname": "Joe", 
    "Lastname": "Doe", 
    "Address": { 
     "Street": "#2140 Taylor Street, 94133", 
     "City": "San Francisco", 
     "Details": { 
      "note": "Pool available" 
     } 
    } 
}, 

"45678": { 
    "Firstname": "Jack", 
    "Lastname": "Plumber", 
    "Address": { 
     "Street": "#111 Sutter St, 94104", 
     "City": "San Francisco", 
     "Details": { 
      "note": "Korean Deli near to main entrance" 
     } 
    } 
} 

आउटपुट

cat data/sample.json.csv 

id,Firstname,Lastname,Address.Street,Address.City,Address.Details.note 
12345,Joe,Doe,"#2140 Taylor Street, 94133",San Francisco,Pool available 
45678,Jack,Plumber,"#111 Sutter St, 94104",San Francisco,Korean Deli near to main entrance 
+0

हाय @ कोर्सीज़िस - मैंने आपके मणि की कोशिश की और निम्न मिला: json2csv त्रुटियों को परिवर्तित करें। जेसन नाम त्रुटि: मुख्य के लिए अपरिभाषित स्थानीय चर या विधि 'त्रुटियां': ऑब्जेक्ट से (irb): 3 /usr/local/opt से /rbenv/versions/2.1.5/bin/irb:11:in '

' – Angela

+0

क्या आप पूर्ण स्टैकट्रैक पोस्ट कर सकते हैं या मुझे एक ईमेल लिख सकते हैं? [email protected] – korCZis

+0

हाँ, मुझे दोबारा प्रयास करने दो .... https: //github.com/korczis/json2csv/issues/2 – Angela

3

@Alex's answer पर लेकिन सीएसवी हेडर और उदाहरण परीक्षण जोड़ने के आधार पर।

# utils.rb 
require "csv" 
module Utils 
    def self.array_of_hashes_to_csv(array_of_hashes) 
    CSV.generate do |csv| 
     csv << array_of_hashes.first.keys 
     array_of_hashes.each { |hash| csv << hash.values } 
    end 
    end 
end 

# utils_test.rb 
class UtilsTest < MiniTest::Unit::TestCase 
    def test_array_of_hashes_to_csv 
    array_of_hashes = [ 
     { :key1 => "value1", :key2 => "value2" }, 
     { :key1 => "value3", :key2 => "value4" } 
    ] 
    expected_result = "key1,key2\nvalue1,value2\nvalue3,value4\n" 
    assert_equal(expected_result, Utils.array_of_hashes_to_csv(array_of_hashes)) 
    end 
end 
1

रूबी कोड जेसन से सीएसवी में कनवर्ट करने के लिए।

उन्हें डबल उद्धृत तारों में परिवर्तित करके सरणी को संभालता है।

#json-to-csv.rb 
require 'json' 
require 'csv' 

file = File.read('./input.json') 
hash = JSON.parse(file) 

CSV.open('./output.csv', 'w') do |csv| 
    headers = hash.first.keys 
    csv << headers 

    hash.each do |item| 
    values = item.values 
    printable_values = Array.new 
    values.each do |value| 

     printable_values << value.to_s.gsub(/\[|\]/,'').gsub(/"/,'\'') 

    end 

    csv << printable_values 

    end 

end 
0

संपादित करें:

नीचे वर्णित यह कार्यक्षमता अब एक gem के रूप में उपलब्ध है। gem install json_converter साथ स्थापित करने के बाद निम्नलिखित स्निपेट एक मान्य JSON स्ट्रिंग या वस्तु से एक CSV उत्पन्न करने के लिए इस्तेमाल किया जा सकता:

require 'json_converter' 
json_converter= JsonConverter.new 

# Assume json is a valid JSON string or object 
csv = json_converter.generate_csv json 

मूल उत्तर:

यदि आपका JSON डेटा अपेक्षाकृत सरल (कोई नेस्टिंग है या सरणी), एलेक्स का जवाब शायद इस समस्या को संभालने का सबसे साफ तरीका है।

हालांकि, अगर आप खाते में सरणियों और नेस्टेड वस्तुओं लेने के लिए जरूरत करना , मैं बंदरगाह इस तरह के एक कनवर्टर का एक web version रूबी के लिए करने का प्रयास किया। यह here पाया जा सकता है। डेटा के वास्तविक पुनर्गठन को संभालने वाली विधियां array_from और flatten हैं।

array_from विधि यह निर्धारित करने का प्रयास करता है कि डेटा के "पंक्ति" किसी दिए गए डेटासेट के लिए कैसा दिखता है। यह सही नहीं है, और आप अलग-अलग डेटासेट के लिए इस भाग को ट्विक करना चाहते हैं।

# Attempt to identify what a "row" should look like 
def array_from(json) 
    queue, next_item = [], json 
    while !next_item.nil? 

    return next_item if next_item.is_a? Array 

    if next_item.is_a? Hash 
     next_item.each do |k, v| 
     queue.push next_item[k] 
     end 
    end 

    next_item = queue.shift 
    end 

    return [json] 
end 

flatten विधि रिकर्सिवली JSON ऑब्जेक्ट (रों) से अधिक दोहराता है, और एक उद्देश्य यह है कि शीर्ष लेख और मूल्यों का प्रतिनिधित्व करता है उत्पन्न करता है। यदि किसी ऑब्जेक्ट को नेस्टेड किया गया है, तो उसके कॉलम के लिए हेडर को इसकी मूल कुंजी (ओं) के साथ प्रीफ़िक्स्ड किया जाएगा, जो / वर्ण से सीमित है।

# The path argument is used to construct header columns for nested elements 
def flatten(object, path='') 
    scalars = [String, Integer, Fixnum, FalseClass, TrueClass] 
    columns = {} 

    if [Hash, Array].include? object.class 
    object.each do |k, v| 
     new_columns = flatten(v, "#{path}#{k}/") if object.class == Hash 
     new_columns = flatten(k, "#{path}#{k}/") if object.class == Array 
     columns = columns.merge new_columns 
    end 

    return columns 
    elsif scalars.include? object.class 
     # Remove trailing slash from path 
     end_path = path[0, path.length - 1] 
     columns[end_path] = object 
     return columns 
    else 
    return {} 
    end 
end 

मूल JSON में किसी भी null मूल्यों देखते हैं, तो आप रूपांतरण प्रयास करने से पहले nil के अलावा कुछ करने के लिए इन बदलने की आवश्यकता होगी - आप आमतौर पर असमान पंक्तियों के साथ खत्म हो जाएगा अगर आप ऐसा नहीं करते। nils_to_strings विधि संभालती है कि:

json = JSON.parse(File.open('in.json').read) 
in_array = array_from json 
in_array.map! { |x| nils_to_strings x } 

out_array = [] 
in_array.each do |row| 
    out_array[out_array.length] = flatten row 
end 

headers_written = false 
CSV.open('out.csv', 'w') do |csv| 
    out_array.each do |row| 
    csv << row.keys && headers_written = true if headers_written === false 
    csv << row.values 
    end 
end 

और अंत में, यहाँ कुछ उदाहरण इनपुट/आउटपुट है::

इनपुट:

# Recursively convert all nil values of a hash to empty strings 
def nils_to_strings(hash) 
    hash.each_with_object({}) do |(k,v), object| 
    case v 
    when Hash 
     object[k] = nils_to_strings v 
    when nil 
     object[k] = '' 
    else 
     object[k] = v 
    end 
    end 
end 

यह इस तरह इस्तेमाल किया जाएगा का एक संक्षिप्त उदाहरण है

{ 
    "Forms": [ 
    { 
     "Form": { 
     "id": "x", 
     "version_id": "x", 
     "name": "x", 
     "category": "", 
     "subcategory": null, 
     "is_template": null, 
     "moderation_status": "x", 
     "display_status": "x", 
     "use_ssl": "x", 
     "modified": "x", 
     "Aggregate_metadata": { 
      "id": "x", 
      "response_count": "x", 
      "submitted_count": "x", 
      "saved_count": "x", 
      "unread_count": "x", 
      "dropout_rate": "x", 
      "average_completion_time": null, 
      "is_uptodate": "x" 
     } 
     }, 
     "User": { 
     "username": "[email protected]" 
     } 
    }, 
    { 
     "Form": { 
     "id": "x", 
     "version_id": "x", 
     "name": "x", 
     "category": "", 
     "subcategory": null, 
     "is_template": null, 
     "moderation_status": "x", 
     "display_status": "x", 
     "use_ssl": "x", 
     "modified": "x", 
     "Aggregate_metadata": { 
      "id": "x", 
      "response_count": "x", 
      "submitted_count": "x", 
      "saved_count": "x", 
      "unread_count": "x", 
      "dropout_rate": "x", 
      "average_completion_time": null, 
      "is_uptodate": "x" 
     } 
     }, 
     "User": { 
     "username": "[email protected]" 
     } 
    } 
    ] 
} 

आउटपुट:

Form/id,Form/version_id,Form/name,Form/category,Form/subcategory,Form/is_template,Form/moderation_status,Form/display_status,Form/use_ssl,Form/modified,Form/Aggregate_metadata/id,Form/Aggregate_metadata/response_count,Form/Aggregate_metadata/submitted_count,Form/Aggregate_metadata/saved_count,Form/Aggregate_metadata/unread_count,Form/Aggregate_metadata/dropout_rate,Form/Aggregate_metadata/average_completion_time,Form/Aggregate_metadata/is_uptodate,User/username 
x,x,x,"","","",x,x,x,x,x,x,x,x,x,x,"",x,[email protected] 
x,x,x,"","","",x,x,x,x,x,x,x,x,x,x,"",x,[email protected] 
0

यह हैडल हेडर & नेस्टेड जेसन हैडल है। इस पर

require 'csv' 
require 'json' 

@headers = [] 
file = File.open('file.json') 
JSON.parse(file.read).each do |h| 
    h.keys.each do |key| 
    @headers << key 
    end 
end 

uniq_headers = @headers.uniq 
file = File.open('file.json') 
finalrow = [] 

JSON.parse(file.read).each do |h| 
    final = {} 
    @headers.each do |key2| 
    final[key2] = h[key2] 
    end 

    finalrow << final 
end 

CSV.open('output.csv' , 'w') do |csv| 
    csv << uniq_headers 
    finalrow.each do |deal| 
    csv << deal.values 
    end 
end 
संबंधित मुद्दे