JSON to CSV 변환기
JSON 배열을 CSV 형식으로 변환
JSON to CSV 변환이란?
JSON to CSV 변환은 JSON 형식의 구조화된 데이터를 스프레드시트, 데이터베이스, 분석 도구가 기본적으로 처리할 수 있는 쉼표로 구분된 값(표 형식)으로 변환합니다. JSON은 고정 스키마 없이 중첩 객체와 배열로 데이터를 저장합니다. CSV는 필드 이름을 정의하는 헤더 행이 있는 행과 열로 데이터를 저장합니다. 이 변환은 API 데이터가 스프레드시트와 데이터베이스에 도달하는 방식입니다.
CSV(Comma-Separated Values)는 RFC 4180으로 정의됩니다. 각 줄이 하나의 레코드이며, 줄 내 필드는 구분자 문자(가장 일반적으로 쉼표)로 구분됩니다. 구분자, 큰따옴표, 줄바꿈이 포함된 필드는 큰따옴표로 묶어야 하며, 내부 따옴표는 두 개를 사용해 이스케이프합니다. 이 이스케이프 처리가 JSON-to-CSV 변환기를 직접 작성할 때 버그가 가장 많이 발생하는 원인입니다.
입력이 일관된 키를 가진 평탄한 객체 배열일 때 변환은 간단합니다. 각 객체가 하나의 행이 되고, 각 고유 키가 열 헤더가 됩니다. 중첩 객체와 배열은 평탄화 단계가 필요하며, 객체 간 키가 일치하지 않으면 누락된 필드를 처리하는 전략(일반적으로 셀을 빈 값으로 남김)이 필요합니다. 신뢰할 수 있는 변환기는 이러한 모든 엣지 케이스를 자동으로 처리합니다.
JSON을 CSV로 변환하는 이유
API는 JSON을 반환하지만 스프레드시트, SQL 데이터베이스, BI 도구는 표 형식 데이터를 필요로 합니다. JSON을 CSV로 변환하면 커스텀 가져오기 스크립트 없이 이러한 시스템 간에 데이터를 이동할 수 있습니다.
JSON to CSV 활용 사례
CSV 구분자 참조
구분자 문자는 각 행의 필드를 구분합니다. 쉼표가 가장 일반적이지만, 특정 상황에서는 다른 구분자가 표준입니다. 잘못된 구분자를 선택하면 파일을 열 때 필드가 합쳐지거나 잘못 분리될 수 있습니다.
| 구분자 | 문자 | 확장자 | 사용 시점 |
|---|---|---|---|
| Comma | , | .csv | Default for most spreadsheets and databases |
| Semicolon | ; | .csv | Standard in locales where comma is a decimal separator (DE, FR, BR) |
| Tab | \t | .tsv | Avoids escaping when field values contain commas or semicolons |
| Pipe | | | .csv | Used in fixed-width legacy systems and some ETL pipelines |
CSV에서 중첩 JSON 처리
CSV는 중첩 객체나 배열을 기본적으로 표현할 방법이 없는 평탄한 형식입니다. JSON에 중첩 구조가 포함된 경우 변환기는 이를 열로 평탄화해야 합니다. 여러 전략이 있으며, 적합한 선택은 CSV가 어떻게 사용될지에 따라 다릅니다.
코드 예제
JSON을 CSV로 프로그래밍 방식으로 변환하려면 헤더 추출, 필드 인용, 구분자 이스케이프 처리가 필요합니다. 대부분의 언어에는 CSV 작성을 위한 내장 또는 표준 라이브러리 지원이 있습니다.
const data = [
{ name: "Alice", age: 30, city: "Berlin" },
{ name: "Bob", age: 25, city: "Tokyo" },
]
// Extract headers from the first object
const headers = Object.keys(data[0])
const csv = [
headers.join(","),
...data.map(row => headers.map(h => {
const val = String(row[h] ?? "")
// Quote fields that contain commas, quotes, or newlines
return val.includes(",") || val.includes('"') || val.includes("\n")
? '"' + val.replace(/"/g, '""') + '"'
: val
}).join(","))
].join("\n")
console.log(csv)
// → name,age,city
// → Alice,30,Berlin
// → Bob,25,Tokyoimport json, csv, io
json_str = '[{"name":"Alice","age":30,"city":"Berlin"},{"name":"Bob","age":25,"city":"Tokyo"}]'
data = json.loads(json_str)
output = io.StringIO()
writer = csv.DictWriter(output, fieldnames=data[0].keys())
writer.writeheader()
writer.writerows(data)
print(output.getvalue())
# → name,age,city
# → Alice,30,Berlin
# → Bob,25,Tokyo# Using jq to convert JSON array to CSV
echo '[{"name":"Alice","age":30},{"name":"Bob","age":25}]' | \
jq -r '(.[0] | keys_unsorted) as $k | $k, (.[] | [.[$k[]]] ) | @csv'
# → "name","age"
# → "Alice",30
# → "Bob",25
# Using Miller (mlr) for streaming conversion
echo '[{"name":"Alice","age":30}]' | mlr --json --ocsv cat
# → name,age
# → Alice,30package main
import (
"encoding/csv"
"encoding/json"
"fmt"
"os"
)
func main() {
jsonStr := `[{"name":"Alice","age":30},{"name":"Bob","age":25}]`
var data []map[string]interface{}
json.Unmarshal([]byte(jsonStr), &data)
w := csv.NewWriter(os.Stdout)
// Write header
headers := []string{"name", "age"}
w.Write(headers)
// Write rows
for _, row := range data {
record := make([]string, len(headers))
for i, h := range headers {
record[i] = fmt.Sprintf("%v", row[h])
}
w.Write(record)
}
w.Flush()
// → name,age
// → Alice,30
// → Bob,25
}