CSV, Json, YAML, Xlsx 변환기
쉼표로 구분된 텍스트 형식인 CSV 데이터를 웹 서비스와 앱 개발에서 표준으로 사용하는 JSON 객체 배열 포맷으로 변환해 주는 데이터 처리 도구입니다. 엑셀(Excel)이나 구글 스프레드시트의 표 데이터를 프로그래밍 환경에서 즉시 활용할 수 있도록 직렬화하며, 인코딩 설정과 평탄화 옵션까지 지원합니다.
1. 여러가지 데이터 포맷들
CSV는 사실상 모든 서비스가 지원하는 범용 표준 포맷입니다. 구글 스프레드시트, 노션, 데이터베이스 관리 도구, 통계 소프트웨어까지 — '내보내기' 버튼을 누르면 십중팔구 CSV 파일이 떨어집니다. 데이터를 주고받는 언어로 오랫동안 자리를 지켜온 형식입니다.
반면 서비스를 개발할 때는 JSON이 훨씬 편합니다. REST API는 JSON을 주고받고, 프론트엔드 차트 라이브러리도 JSON 배열을 기대하며, Node.js나 Python 코드에서도 JSON을 직접 가져다 쓸 수 있습니다. CSV처럼 파서를 별도로 거칠 필요가 없습니다.
YAML은 또 다른 맥락에서 빛납니다. 사람이 직접 읽고 수정하는 설정 파일에 어울립니다. GitHub Actions 워크플로, Kubernetes 매니페스트, Docker Compose 파일이 모두 YAML로 작성됩니다. 중괄호 없이 들여쓰기만으로 계층 구조를 표현할 수 있어 긴 설정 파일도 비교적 읽기 쉽습니다.
XLSX는 기획자와 비개발자의 영역입니다. 셀 서식, 수식, 여러 시트를 포함한 복잡한 표 문서는 엑셀 파일로 공유되는 경우가 여전히 많습니다. 개발 팀이 직접 열어 내용을 확인하려면 변환이 먼저입니다.
문제는 이 네 가지가 서로 소통하지 않는다는 점입니다. 마케팅 팀이 보낸 CSV 고객 데이터를 API 서버에 넣으려면 JSON으로 바꿔야 하고, 기획자가 정리한 XLSX 상품 목록을 배포 파이프라인에 쓰려면 YAML이나 JSON이 필요합니다. 서비스간 데이터를 연동할 때 포맷을 맞추는 일이 생각보다 자주 생깁니다.
그 변환 작업을 빠르게 수행하기 위해 온라인에서 무료로 사용가능한 변환 도구를 만들었습니다.
2. 도구 사용법 및 가이드
표 형태의 데이터를 구조화된 JSON 리스트로 변환하는 단계별 방법입니다.

a. 원시 데이터 붙여넣기
엑셀 등에서 복사한 CSV 텍스트를 좌측 입력 패널에 붙여넣습니다. 첫 번째 행은 자동으로 각 객체의 키(Key) 값으로 할당됩니다.
b. CSV 파일 업로드
로컬 환경의 .csv 파일을 드래그 앤 드롭하여 불러옵니다. 대용량 파일도 브라우저에서 직접 파싱하여 처리 속도가 매우 빠릅니다.
c. 인코딩 문제 해결
윈도우 엑셀 등에서 저장된 파일이 깨져 보인다면 하단의 읽기 인코딩 설정을 UTF-8 또는 EUC-KR로 변경하여 문자를 복원합니다.
d. 구조적 평탄화 설정
중첩 구조가 필요한 경우 평탄화(Flatten) 옵션을 활성화하거나 비활성화하여 원하는 JSON 계층 구조를 구성합니다.
e. 데이터 다운로드
변환 결과인 JSON 문자열을 복사하거나 저장 버튼을 눌러 파일로 소장합니다.
3. CSV와 JSON 중첩구조 해결
가장 상호 변환이 많이 필요한 두 포맷을 중점적으로 비교해 보겠습니다. 요즘에는 YAML 형식을 많이 사용하지만, JSON과 같이 묶어서 생각해도 무방하다고 생각합니다.
이 세션에서 다루는 내용은 CSV의 2차원 평면 데이터 구조와 Json의 n차원 데이터 구조를 어떻게 상호 변환 했는지에 대해서 설명하고자 합니다.
우선 두 포맷의 데이터 형식 및 특성을 아래에 정리하였습니다.
// CSV — 2차원 테이블 (행과 열)
name,age,city
홍길동,30,서울
김철수,25,부산
// JSON — 객체 배열 (키-값 쌍의 리스트)
[
{ "name": "홍길동", "age": 30, "city": "서울" },
{ "name": "김철수", "age": 25, "city": "부산" }
]
| 특성 | CSV | JSON |
|---|---|---|
| 데이터 구조 | 2차원 테이블 (행 × 열) | 중첩 가능한 트리 구조 |
| 사람 가독성 | 소량 데이터에서 우수 | 중첩 구조에서 우수 |
| 파일 크기 | 작음 (키 이름 반복 없음) | 큼 (키 이름이 매 객체마다 반복) |
| 타입 정보 | 없음 (모두 문자열) | 명시적 (string, number, boolean, null) |
| 중첩 데이터 | 표현 불가 (평면 구조) | 자유로운 중첩 가능 |
| 표준 | RFC 4180 | RFC 8259 |
| 주요 사용처 | 스프레드시트, DB 내보내기, 통계 | 웹 API, 설정 파일, NoSQL DB |
b. 중첩 구조를 어떻게 해결했는가
위에서 보시다 싶이 CSV는 본질적으로 2차원 테이블입니다. 깊이가 있는 중첩 객체나 여러 항목이 담긴 배열을 그대로 넣을 수 없습니다. 이 도구는 세 가지 원리로 이 한계를 넘어갑니다.
1. 깊은 객체는 이름을 이어 붙인다.
계층 구조로 된 필드는 상위 이름과 하위 이름을 점(.)으로 연결해 하나의 컬럼으로 만듭니다. 얼마나 깊이 중첩되어 있든 끝까지 파고들어 원시 값이 나오면 그 경로 전체가 컬럼 이름이 됩니다. 반대로 JSON으로 되돌릴 때는 점을 기준으로 다시 나눠 원래 계층 구조를 복원합니다.
[
{
"orderId": "ORD-001",
"customer": { "name": "Alice", "tier": "VIP" }
},
{
"orderId": "ORD-002",
"customer": { "name": "Bob", "tier": "Standard" }
}
]
orderId,customer.name,customer.tier
ORD-001,Alice,VIP
ORD-002,Bob,Standard
2. 단순 배열은 셀 하나에 압축한다.
문자열이나 숫자 같은 단순 값의 나열은 JSON 텍스트 형태로 직렬화해서 셀 하나에 담습니다. 다시 읽을 때는 그 셀 값이 배열처럼 보이면 자동으로 파싱해 원래 배열로 복원합니다.
[
{ "orderId": "ORD-001", "tags": ["urgent", "domestic"] },
{ "orderId": "ORD-002", "tags": ["international"] }
]
orderId,tags
ORD-001,"[""urgent"",""domestic""]"
ORD-002,"[""international""]"
3. 객체 배열은 행을 늘린다.
각 항목이 여러 필드를 가진 배열은 앞의 방식으로 해결할 수 없습니다. 이 도구는 배열의 항목 수만큼 행을 추가하는 방식으로 처리합니다. 상위 필드 값을 각 행에 반복하면서 배열 항목의 필드를 접두사가 붙은 컬럼으로 분리합니다. JSON으로 되돌릴 때는 같은 상위 필드 값을 공유하는 연속된 행들을 하나의 원본 객체로 묶고, 분리된 행들을 다시 배열로 재조립합니다.
[
{
"orderId": "ORD-001",
"items": [
{ "product": "Keyboard", "qty": 1 },
{ "product": "Mouse", "qty": 2 }
]
},
{
"orderId": "ORD-002",
"items": [
{ "product": "Monitor", "qty": 1 }
]
}
]
orderId,items.product,items.qty
ORD-001,Keyboard,1
ORD-001,Mouse,2
ORD-002,Monitor,1
4. 실무에서 데이터 포맷 변환이 필요한 상황들
스프레드시트 데이터를 API 서버에 넣어야 할 때
구글 스프레드시트나 엑셀로 관리하던 상품 목록, 사용자 데이터, 콘텐츠 목록을 서버 API에 일괄 등록해야 하는 경우가 있습니다. API는 대부분 JSON 요청 본문을 기대하기 때문에 CSV나 XLSX를 그대로 넣을 수 없습니다. 변환 후 각 행이 하나의 JSON 객체가 되면 코드 한 줄로 반복 등록 처리가 가능합니다.
DB 쿼리 결과를 대시보드에 연결할 때
데이터베이스 관리 도구에서 쿼리 결과를 CSV로 내보낸 뒤 대시보드나 차트 라이브러리에 연결하려면 JSON 배열로 바꿔야 합니다. Chart.js, Recharts, D3 같은 라이브러리는 모두 JSON 배열 형태의 데이터를 기대합니다. 컬럼 이름이 그대로 JSON 키가 되므로 별도 매핑 작업 없이 바로 연결할 수 있습니다.
기획 문서를 개발 환경 설정으로 옮길 때
기획 팀이 엑셀로 정리한 기능 목록, 카테고리 구조, 다국어 번역 텍스트를 개발 환경에서는 JSON 설정 파일로 관리하는 경우가 많습니다. 매번 손으로 값을 옮기다 보면 오탈자가 생기고 누락이 발생합니다. 한 번에 변환하면 원본 그대로 반영되어 실수를 줄일 수 있습니다.
YAML 설정 파일의 구조를 확인할 때
GitHub Actions 워크플로나 Kubernetes 매니페스트를 작성하다 보면 들여쓰기 실수나 타입 문제가 생겼는지 확인하고 싶을 때가 있습니다. YAML을 JSON으로 변환하면 중괄호와 따옴표로 구조가 명확하게 드러나 의도와 다르게 파싱된 부분을 쉽게 찾을 수 있습니다.
레거시 시스템과 신규 시스템을 연결할 때
오래된 시스템이 월별 데이터를 XLSX로 내보내는데 신규 분석 도구나 파이프라인은 JSON만 받는 상황이 있습니다. 매달 같은 변환 작업을 반복하게 되는데, 포맷만 맞추면 이후 처리를 자동화할 수 있습니다. 외부 파트너사에서 CSV로 데이터를 받아 내부 시스템의 YAML 설정에 합쳐야 하는 경우도 마찬가지입니다.
테스트 데이터를 코드로 바로 임포트할 때
테스트 픽스처 데이터를 엑셀로 관리하다 테스트 코드에서 직접 불러오고 싶을 때도 변환이 필요합니다. XLSX를 JSON으로 바꿔 저장해 두면 require나 import로 바로 불러와 테스트에 사용할 수 있습니다. 테스트 데이터 관리와 코드 사이의 간격이 줄어듭니다.
5. 변환시 발생할 수 있는 문제들
CSV 변환 시
가장 흔한 문제는 인코딩입니다. 윈도우 환경의 엑셀은 기본적으로 EUC-KR이나 CP949로 CSV를 저장합니다. UTF-8로 열면 한글이 모두 깨집니다. 이 도구는 파일 업로드 시 인코딩을 자동 감지하고, 틀렸을 경우 하단의 읽기 인코딩 선택기로 수동 변경할 수 있습니다.
셀 안에 쉼표나 줄바꿈이 포함된 경우도 문제가 됩니다. CSV 명세상 이런 값은 큰따옴표로 감싸야 하는데, 따옴표 처리가 제대로 되지 않으면 열이 어긋납니다. 이 도구는 PapaParse 라이브러리를 사용해 RFC 4180 규격에 맞게 파싱하므로 대부분의 경우 올바르게 처리됩니다.
전화번호나 우편번호처럼 숫자로만 이루어졌지만 앞자리 0이 의미 있는 값은 자동 타입 변환으로 0이 사라집니다. 010-1234-5678이 10-1234-5678이 되거나 02123이 2123이 되는 식입니다. CSV는 타입 정보가 없어 파서가 숫자처럼 보이면 숫자로 변환하기 때문입니다.
JSON 변환 시
중첩 깊이가 깊거나 배열 안에 배열이 있는 구조를 CSV로 변환할 때는 컬럼 수가 크게 늘어납니다. 객체 배열이 행 폭발로 처리되면 원본보다 행 수도 증가합니다. 복잡한 중첩 구조를 평면 표로 만드는 과정에서 데이터 형태가 달라진다는 점을 염두에 두어야 합니다.
배열 안에 다시 배열이 있는 경우, 내부 배열은 JSON 문자열로 직렬화되고 외부 배열만 행 폭발로 처리됩니다. 구조가 복잡할수록 역변환 시 원본과 완전히 일치하지 않을 수 있습니다.
YAML 변환 시
YAML은 타입 추론이 너무 적극적입니다. 따옴표 없이 쓴 yes, no, true, false는 boolean으로 변환되고, 2024-01-15는 날짜 객체가 됩니다. 0x1A는 26으로 해석됩니다. 나라 코드 NO(노르웨이)가 false가 되는 고전적인 실수가 여기서 생깁니다. 이 도구로 YAML을 JSON으로 변환했을 때 예상과 다른 타입이 보인다면 원본 YAML에서 문제가 되는 값을 따옴표로 감싸야 합니다.
탭과 스페이스 혼용은 YAML 파서가 즉시 거부합니다. 들여쓰기 오류가 발생하면 변환 자체가 실패합니다.
XLSX 변환 시
셀 병합이 있는 시트는 파싱 결과가 예상과 다릅니다. 병합된 영역에서 첫 번째 셀만 값이 있고 나머지는 빈 문자열로 채워지기 때문에, 테이블처럼 보이는 스프레드시트가 실제로는 구멍이 많은 데이터로 나올 수 있습니다.
수식이 들어있는 셀은 계산된 결과값이 아닌 수식 문자열(=SUM(A1:A10))로 읽히는 경우가 있습니다. 엑셀에서 한 번 저장 후 닫았다가 다시 열어 캐싱된 계산값이 파일에 기록된 경우에는 정상적으로 읽히지만, 수식만 있고 캐싱값이 없는 파일이라면 수식 문자열이 그대로 나옵니다.
시트가 여러 개인 경우 이 도구는 첫 번째 시트만 변환합니다. 두 번째 이후 시트의 데이터가 필요하다면 엑셀에서 해당 시트를 별도 파일로 저장한 뒤 다시 업로드해야 합니다.
6. 생각해볼 거리
CSV가 50년 넘게 살아남은 이유는 무엇일까요?
JSON, XML, Parquet 같은 더 구조화된 형식이 등장했지만, CSV는 여전히 데이터 교환의 최전선에 있습니다. 가장 큰 이유는 진입 장벽이 거의 없다는 점입니다. 메모장으로 열 수 있고, 엑셀에서 바로 편집할 수 있으며, 프로그래밍 언어를 몰라도 이해할 수 있습니다. 비개발자도 데이터를 생산하고 소비할 수 있는 유일한 형식이라는 점이 CSV의 가장 강력한 생존 이유입니다.
대용량 데이터를 다룰 때 CSV와 JSON 대신 어떤 형식을 써야 할까요?
수십만~수억 행의 데이터를 다룬다면 Apache Parquet이나 Apache Arrow 같은 열 기반(columnar) 이진 포맷을 고려해야 합니다. CSV는 행 단위 접근에는 적합하지만, 특정 열만 읽거나 집계 연산을 수행할 때는 전체 파일을 파싱해야 합니다. Parquet은 열별로 데이터를 저장하므로 필요한 컬럼만 읽을 수 있어 I/O와 메모리 사용이 크게 줄어듭니다. Python의 pandas나 Polars에서 read_parquet()을 사용하면 CSV 대비 수십 배 빠른 속도를 체감할 수 있습니다.
JSON 배열로 변환하면 동일 키가 매 객체마다 반복됩니다. 비효율 아닌가요?
맞습니다. 10개 컬럼 × 10,000행 데이터를 JSON 배열로 변환하면 키 이름이 10만 번 반복되어 CSV보다 파일 크기가 2~3배 커집니다. 이 문제를 해결하는 방법은 여러 가지입니다. gzip 압축을 적용하면 반복되는 키 이름이 효율적으로 압축되어 실전송 크기 차이가 크게 줄어듭니다. 또는 NDJSON(Newline Delimited JSON) 형식을 사용하면 스트리밍 파싱이 가능해져 메모리 효율도 개선됩니다. 데이터 저장보다는 API 통신을 위한 교환 형식으로 JSON을 사용한다면 이 오버헤드는 충분히 감수할 만합니다.
브라우저 탭 하나로 엑셀에서 내보낸 CSV 데이터를 인코딩 걱정 없이 JSON 배열로 즉시 변환할 수 있습니다 — 데이터베이스 임포트부터 차트 라이브러리 연동까지, 데이터 포맷 변환에 쏟던 시간이 사라집니다. 그것만으로도 이 도구의 역할은 충분하다고 생각합니다.