← 전체 글

JSON을 CSV로(그리고 다시) 변환하는 방법

JavaScript, Python, 온라인에서 JSON ↔ CSV 변환. array-of-objects 매핑, 따옴표 규칙, 중첩 값, 타입 강제 변환을 다룬다.

JSON 은 API 의 언어, CSV 는 스프레드시트·데이터베이스·분석가의 언어입니다. 둘 사이의 변환은 일상 작업입니다 —— API 응답을 Excel 로 내보내거나, 스프레드시트를 JSON 으로 변환해 import 하는 식입니다. 본 가이드는 JavaScript, Python, 그리고 브라우저에서 JSON 을 CSV 로, CSV 를 JSON 으로 변환하는 방법과 사람들이 자주 걸리는 엣지 케이스(중첩 데이터, 따옴표, 타입)를 다룹니다.

핵심 매핑: 객체 배열 ⇄ 행

CSV 파일은 테이블입니다: 열 이름의 헤더 행 하나, 그다음 레코드당 한 행. 이 테이블에 자연스럽게 매핑되는 JSON 형태는 객체 배열 입니다. 각 객체가 한 행, 각 키가 한 열이 됩니다.

// JSON
[
  { "id": 1, "name": "Ada Lovelace", "active": true },
  { "id": 2, "name": "Bob Khan", "active": false }
]
# CSV
id,name,active
1,Ada Lovelace,true
2,Bob Khan,false

헤더는 모든 객체 키의 합집합입니다(필드가 다른 객체들도 정렬됩니다). 각 행은 각 열에 해당하는 값을 가져옵니다.

JavaScript 에서 JSON 을 CSV 로 변환하는 방법

JavaScript 에는 내장 JSON.toCSV 가 없지만, 변환 자체는 짧습니다. 진짜 작업은 이스케이프 뿐입니다: 쉼표, 큰따옴표, 줄바꿈을 포함한 값은 큰따옴표로 감싸고, 내부 따옴표는 두 번으로 늘려야 합니다.

function jsonToCsv(rows) {
  if (!rows.length) return '';
  const headers = [...new Set(rows.flatMap(Object.keys))];

  const escape = (v) => {
    if (v == null) return '';
    const s = typeof v === 'object' ? JSON.stringify(v) : String(v);
    return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  };

  const lines = [headers.join(',')];
  for (const row of rows) {
    lines.push(headers.map((h) => escape(row[h])).join(','));
  }
  return lines.join('\n');
}

typeof v === 'object' 분기에 주목하세요: 중첩 객체나 배열은 평면 CSV 표현이 없으므로 관례는 셀에 JSON 텍스트로 직렬화하는 것입니다. 자세한 내용은 아래에 있습니다.

JavaScript 에서 CSV 를 JSON 으로 변환하는 방법

반대 방향의 함정은 CSV 를 올바르게 파싱하는 것입니다 —— 필드는 따옴표 에 쉼표와 줄바꿈을 가질 수 있으므로 단순히 split(',') 할 수 없습니다. 작은 상태기계를 쓰거나(또는 프로덕션에서는 papaparse 같은 라이브러리를) 사용하세요:

function csvToJson(text) {
  const rows = [];
  let row = [], field = '', inQuotes = false;
  for (let i = 0; i < text.length; i++) {
    const c = text[i];
    if (inQuotes) {
      if (c === '"' && text[i + 1] === '"') { field += '"'; i++; }
      else if (c === '"') inQuotes = false;
      else field += c;
    } else if (c === '"') inQuotes = true;
    else if (c === ',') { row.push(field); field = ''; }
    else if (c === '\n') { row.push(field); rows.push(row); row = []; field = ''; }
    else if (c !== '\r') field += c;
  }
  if (field || row.length) { row.push(field); rows.push(row); }

  const [headers, ...data] = rows;
  return data.map((cells) =>
    Object.fromEntries(headers.map((h, i) => [h, cells[i] ?? ''])));
}

Python 에서 JSON 과 CSV 를 상호 변환

Python 표준 라이브러리에 이 기능이 내장되어 있습니다 —— 의존성 불필요.

import csv, json, io

# JSON -> CSV
rows = json.loads(json_text)
buf = io.StringIO()
writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
csv_text = buf.getvalue()

# CSV -> JSON
rows = list(csv.DictReader(io.StringIO(csv_text)))
json_text = json.dumps(rows, indent=2)

실제로 중요한 엣지 케이스

중첩된 객체와 배열

CSV 는 평면이고 JSON 은 아닙니다. 값이 객체나 배열일 때 두 가지 선택지가 있습니다: 단일 셀에 JSON 으로 직렬화(간단하고 가역)하거나 평탄화해서 address.cityaddress.zip 같은 여러 열로 만들기(읽기 쉽지만 손실이 있고 되돌리기 어려움). 왕복이 필요하면 셀 안 JSON 이 안전합니다.

CSV 는 타입을 잃습니다

CSV 에는 타입이 없습니다 —— 모든 필드는 텍스트입니다. CSV → JSON 변환 시, 의도적으로 숫자로 강제하지 않는 한 "1" 은 문자열입니다. 007 같은 값(문자열로 유지해야 하는 우편번호/ID)이나 숫자로 정밀도를 잃는 큰 정수에 주의하세요. 왕복이 무손실일 때만 강제 변환하세요.

따옴표와 구분자

쉼표, 따옴표, 줄바꿈을 포함하는 필드는 항상 따옴표로 묶으세요. 일부 로케일(유럽 Excel 에서 흔함)은 구분자로 ; 을 씁니다 —— CSV 가 어떤 열에서 이상해 보이면 먼저 구분자부터 확인하세요.

키가 일관되지 않을 때

JSON 객체들이 모두 같은 키를 갖지 않는다면 모든 키의 합집합으로 헤더를 만들고 빠진 셀은 비워 두세요 —— 첫 객체가 모든 열을 정의한다고 가정하지 마세요.

Excel 과 UTF-8 BOM

CSV 를 Excel 에서 열 예정이고 비 ASCII 문자가 있다면 UTF-8 BOM(바이트 0xEF 0xBB 0xBF)을 앞에 추가하세요. Excel 은 BOM 없는 UTF-8 을 레거시 인코딩으로 읽어 악센트/아시아 문자를 깨뜨립니다. 대부분의 CSV 라이브러리는 옵션으로 BOM 을 출력할 수 있습니다.

// JavaScript —— BOM 을 써서 Excel 이 UTF-8 을 올바르게 읽도록
const out = '\uFEFF' + jsonToCsv(rows);

다른 구분자(CSV vs TSV vs ;)

"CSV" 가 항상 쉼표 구분은 아닙니다. 흔한 변종:

  • TSV —— 탭 구분; 값이 쉼표를 자주 포함할 때 더 안전.
  • 유럽 Excel 은 소수점이 쉼표인 로케일에서 구분자로 ; 을 출력.

출력이 이상한 단일 열에 몰려 보인다면, 파일이 리더가 기대하는 것과 다른 구분자를 씁니다. 하나로 표준화하세요(지역 간 Excel 에는 , + BOM 의 CSV, 엔지니어링 파이프라인에는 TSV).

현실 세계 CSV 에는 PapaParse

사용자에게서 오는 CSV 를 브라우저/Node 에서 파싱하려면 PapaParse 를 쓰세요 —— 구분자 감지, 따옴표 필드, 다중행 값, 헤더 행, 그리고 숫자/불리언 강제를 위한 dynamicTyping 을 처리합니다. 위 손수 작성 스니펫은 신뢰할 수 있는 단순 입력에는 괜찮지만 규모에서는 PapaParse 가 손에 잡힐 도구입니다.

JSON 을 CSV 로 온라인 변환 —— 설정 불필요

일회성 변환이라면 코드를 완전히 건너뛰세요. JSON 을 fixjson 의 JSON to CSV 변환기 에 붙여 넣고 To CSV 를 클릭하거나, CSV 를 붙여 넣고 To JSON 을 클릭하세요. 따옴표 처리, 키 합집합, 타입 강제를 자동으로 처리하며 모두 브라우저에서 실행됩니다 —— 업로드 없음, 고객 레코드나 내부 export 가 포함된 데이터에서 중요한 점입니다.

자주 묻는 질문

JSON 을 CSV 로 변환하려면?

JSON 객체 배열을 가져와 모든 키의 합집합으로 헤더 행을 만들고, 객체마다 한 행씩 씁니다 —— 쉼표, 따옴표, 줄바꿈을 포함한 값은 따옴표로 감쌉니다. Python 에서는 csv.DictWriter, JavaScript 에서는 작은 함수로, 또는 온라인 변환기 에 붙여 넣으세요.

CSV 를 JSON 으로 변환하려면?

CSV 를 파싱하고(따옴표 필드를 존중) 첫 행을 헤더로 처리한 다음, 이어지는 각 행을 헤더를 키로 하는 객체에 매핑하세요. 강제 변환을 하지 않는 한 모든 값은 문자열로 도착함을 기억하세요.

중첩된 JSON 객체는 CSV 에서 어떻게 표현되나요?

CSV 는 중첩할 수 없으므로 중첩 객체나 배열은 보통 단일 셀에 JSON 텍스트로 쓰거나 address.city 같은 점 표기 열로 평탄화합니다. 셀 안 JSON 이 가역적인 선택지입니다.

JSON 을 CSV 로 온라인에서 무료로 변환할 수 있나요?

네 —— fixjson 의 변환기 가 양방향을 무료로, 전적으로 브라우저에서, 계정·업로드 없이 처리합니다.

관련 도구와 가이드