将动态JSON转换为CSV在Golang中的实现

huangapple go评论79阅读模式
英文:

Converting dynamic JSON to CSV in Golang

问题

我尝试将动态JSON转换为CSV,我调查了一些库和答案,但没有找到一个显著的解决方案。

这个例子这个例子可能会有所帮助,但我无法将JSON的结构添加到我的代码中,因为JSON是动态的。

在Python和JS中,我看到了以下这些例子:

Python:

# Python program to convert
# JSON file to CSV

import json
import csv

# Opening JSON file and loading the data
# into the variable data
with open('data.json') as json_file:
    data = json.load(json_file)

employee_data = data['emp_details']

# now we will open a file for writing
data_file = open('data_file.csv', 'w')

# create the csv writer object
csv_writer = csv.writer(data_file)

# Counter variable used for writing
# headers to the CSV file
count = 0

for emp in employee_data:
    if count == 0:

        # Writing headers of CSV file
        header = emp.keys()
        csv_writer.writerow(header)
        count += 1

    # Writing data of CSV file
    csv_writer.writerow(emp.values())

data_file.close()

JS:

const items = json3.items
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(items[0])
const csv = [
  header.join(','), // header row first
  ...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
].join('\r\n')

console.log(csv)

这些代码可以帮助你轻松地将动态JSON转换为CSV。

示例输入和输出:

JSON输入:

[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]

CSV输出:

"name","age"
"John","21"
"Noah","23"
"Justi","25"

那么,我该如何在Go中将动态JSON转换为CSV呢?

PS:我发现了一个Golang库(json2csv),可以帮助进行转换,但只能在命令提示符中使用。

还有一些在线工具,例如:

https://csvjson.com/json2csv

https://data.page/json/csv

英文:

I tried to convert dynamic JSON to CSV, I investigate libs and answers I can't find a remarkable thing.

This and this examples could be helpful but I can't add the JSON's struct to my code, JSON is dynamic.

In Python & JS, I saw these examples;

Python;

# Python program to convert
# JSON file to CSV
 
 
import json
import csv
 
 
# Opening JSON file and loading the data
# into the variable data
with open('data.json') as json_file:
    data = json.load(json_file)
 
employee_data = data['emp_details']
 
# now we will open a file for writing
data_file = open('data_file.csv', 'w')
 
# create the csv writer object
csv_writer = csv.writer(data_file)
 
# Counter variable used for writing
# headers to the CSV file
count = 0
 
for emp in employee_data:
    if count == 0:
 
        # Writing headers of CSV file
        header = emp.keys()
        csv_writer.writerow(header)
        count += 1
 
    # Writing data of CSV file
    csv_writer.writerow(emp.values())
 
data_file.close()

JS;

const items = json3.items
const replacer = (key, value) => value === null ? '' : value // specify how you want to handle null values here
const header = Object.keys(items[0])
const csv = [
  header.join(','), // header row first
  ...items.map(row => header.map(fieldName => JSON.stringify(row[fieldName], replacer)).join(','))
].join('\r\n')

console.log(csv)

These codes help convert dynamic JSON to CSV easily.

Example input & output;

JSON(input);

[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]

CSV(output);

"name","age"
"John","21"
"Noah","23"
"Justi","25"

So how can I convert dynamic JSON to CSV in Go?

PS: I discover a Golang lib(json2csv) that helps to convert but only works on command prompt.

I few online tools for example;

https://csvjson.com/json2csv

https://data.page/json/csv

答案1

得分: 2

经过调查,我使用yukithm/json2csv包来处理它。

package main

import (
	"bytes"
	"encoding/json"
	"github.com/yukithm/json2csv"
	"log"
	"os"
)

func main() {
	b := &bytes.Buffer{}
	wr := json2csv.NewCSVWriter(b)
	j, _ := os.ReadFile("your-input-path\\input.json")
	var x []map[string]interface{}

	// 解组json
	err := json.Unmarshal(j, &x)
	if err != nil {
		log.Fatal(err)
	}

	// 将json转换为CSV
	csv, err := json2csv.JSON2CSV(x)
	if err != nil {
		log.Fatal(err)
	}

	// CSV字节转换和写入...
	err = wr.WriteCSV(csv)
	if err != nil {
		log.Fatal(err)
	}
	wr.Flush()
	got := b.String()

	//以下行打印CSV
	println(got)

	// 如果需要,创建文件并追加文本
	createFileAppendText("output.csv", got)
}

//
func createFileAppendText(filename string, text string) {
	f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}

	defer f.Close()

	if _, err = f.WriteString(text); err != nil {
		panic(err)
	}
}

input.json;

[
  {
    "Name": "Japan",
    "Capital": "Tokyo",
    "Continent": "Asia"
  },
  {
    "Name": "Germany",
    "Capital": "Berlin",
    "Continent": "Europe"
  },
  {
    "Name": "Turkey",
    "Capital": "Ankara",
    "Continent": "Europe"
  },
  {
    "Name": "Greece",
    "Capital": "Athens",
    "Continent": "Europe"
  },
  {
    "Name": "Israel",
    "Capital": "Jerusalem",
    "Continent": "Asia"
  }
]

output.csv

/Capital,/Continent,/Name
Tokyo,Asia,Japan
Berlin,Europe,Germany
Ankara,Europe,Turkey
Athens,Europe,Greece
Jerusalem,Asia,Israel
英文:

After investigation, I handle it with yukithm/json2csv package.

package main

import (
	"bytes"
	"encoding/json"
	"github.com/yukithm/json2csv"
	"log"
	"os"
)

func main() {
	b := &bytes.Buffer{}
	wr := json2csv.NewCSVWriter(b)
	j, _ := os.ReadFile("your-input-path\\input.json")
	var x []map[string]interface{}

	// unMarshall json
	err := json.Unmarshal(j, &x)
	if err != nil {
		log.Fatal(err)
	}

	// convert json to CSV
	csv, err := json2csv.JSON2CSV(x)
	if err != nil {
		log.Fatal(err)
	}

	// CSV bytes convert & writing...
	err = wr.WriteCSV(csv)
	if err != nil {
		log.Fatal(err)
	}
	wr.Flush()
	got := b.String()

	//Following line prints CSV
	println(got)

	// create file and append if you want
	createFileAppendText("output.csv", got)
}

//
func createFileAppendText(filename string, text string) {
	f, err := os.OpenFile(filename, os.O_APPEND|os.O_WRONLY|os.O_CREATE, 0600)
	if err != nil {
		panic(err)
	}

	defer f.Close()

	if _, err = f.WriteString(text); err != nil {
		panic(err)
	}
}

input.json;

[
  {
    "Name": "Japan",
    "Capital": "Tokyo",
    "Continent": "Asia"
  },
  {
    "Name": "Germany",
    "Capital": "Berlin",
    "Continent": "Europe"
  },
  {
    "Name": "Turkey",
    "Capital": "Ankara",
    "Continent": "Europe"
  },
  {
    "Name": "Greece",
    "Capital": "Athens",
    "Continent": "Europe"
  },
  {
    "Name": "Israel",
    "Capital": "Jerusalem",
    "Continent": "Asia"
  }
]

output.csv

/Capital,/Continent,/Name
Tokyo,Asia,Japan
Berlin,Europe,Germany
Ankara,Europe,Turkey
Athens,Europe,Greece
Jerusalem,Asia,Israel

答案2

得分: 0

将以下内容粘贴到 https://github.com/yukithm/json2csv/blob/master/cmd/json2csv/main.go 并将该函数插入到 main 函数中。

func stackoverflow() {

	jsonStr := `
[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]`

	buff := bytes.NewBufferString(jsonStr)

	data, _ := readJSON(buff)

	results, _ := json2csv.JSON2CSV(data)

	headerStyle := headerStyleTable["jsonpointer"]
	err := printCSV(os.Stdout, results, headerStyle, false)
	if err != nil {
		log.Fatal(err)
	}
}

这对我有效。

➜  json2csv git:(master) ✗ go run main.go 
/age,/name
21,John
23,Noah
25,Justin
英文:

Paste this to https://github.com/yukithm/json2csv/blob/master/cmd/json2csv/main.go and insert the func to main.

func stackoverflow() {

	jsonStr := `
[
  {
    "name": "John",
    "age": "21"
  },
  {
    "name": "Noah",
    "age": "23"
  },
  {
    "name": "Justin",
    "age": "25"
  }
]`

	buff := bytes.NewBufferString(jsonStr)

	data, _ := readJSON(buff)

	results, _ := json2csv.JSON2CSV(data)

	headerStyle := headerStyleTable["jsonpointer"]
	err := printCSV(os.Stdout, results, headerStyle, false)
	if err != nil {
		log.Fatal(err)
	}
}

It works for me.

➜  json2csv git:(master) ✗ go run main.go 
/age,/name
21,John
23,Noah
25,Justin

huangapple
  • 本文由 发表于 2022年8月10日 16:17:29
  • 转载请务必保留本文链接:https://go.coder-hub.com/73302954.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定