- 공유 링크 만들기
- X
- 이메일
- 기타 앱
이 글의 목적은 엑셀에서 CSV 파일을 UTF-8로 정확히 저장하여 한글 깨짐을 방지하고, 버전·운영체제·시스템 요구조건에 따른 예외 상황까지 현장에서 바로 적용할 수 있도록 실무 절차와 점검표, 자동화 스크립트를 제공하는 것이다.
왜 UTF-8인가: 한글 깨짐의 근본 원인 이해
CSV는 구조상 텍스트와 구분자만 포함하는 단순 포맷이라 인코딩을 명시하지 않는다. 윈도우의 오래된 생태계는 기본적으로 ANSI(윈도우-949 등)를 사용한 반면, 웹·클라우드·리눅스 기반 시스템은 UTF-8을 표준으로 채택하는 경향이 크다. 엑셀에서 기본 CSV로 저장하면 시스템/버전에 따라 ANSI나 다른 코드페이지가 적용될 수 있어 한글이 물음표·깨진 문자로 보일 수 있다. UTF-8로 저장하고, 필요 시 BOM(Byte Order Mark) 포함 여부를 맞추면 호환성이 크게 향상된다.
가장 빠른 해결: 최신 엑셀에서 바로 UTF-8로 저장
다음 절차는 Microsoft 365 및 최신 엑셀 버전에 해당한다.
- 파일 → 다른 이름으로 저장 을 선택한다.
- 파일 형식 에서 CSV UTF-8(쉼표로 분리)(*.csv) 를 선택한다.
- 저장 을 클릭한다.
맥(Excel for Mac)에서 UTF-8 CSV 저장
- 파일 → 다른 이름으로 저장 또는 사본 저장 을 선택한다.
- 파일 형식 에서 CSV UTF-8(쉼표로 분리)(*.csv) 를 선택한다.
- 저장 을 클릭한다.
맥 환경에서는 기본 문자셋이 유니코드 기반이라 윈도우 대비 인코딩 충돌이 적지만, 대상 시스템(예: 레거시 ERP, 장비 로거)이 BOM을 싫어하는 경우가 있어 하단의 BOM 제어 방법을 참고한다.
구버전 엑셀·CSV(쉼표로 분리)(*.csv)만 있는 경우 대안
구버전 엑셀에서는 CSV UTF-8 옵션이 보이지 않을 수 있다. 아래 3가지 경로 중 하나를 사용한다.
방법 A. 메모장(또는 코드 편집기)로 재인코딩
- 엑셀에서 CSV(쉼표로 분리)(*.csv) 로 저장한다.
- 메모장으로 연다 → 다른 이름으로 저장 → 인코딩 에서 UTF-8 을 선택하고 저장한다.
방법 B. PowerShell로 UTF-8(BOM/무BOM) 변환
윈도우에서 명령줄로 정확한 인코딩을 강제할 수 있다.
# PowerShell 5.x: 기본 UTF8는 BOM 포함일 수 있음 Get-Content .\input.csv | Set-Content -Encoding UTF8 .\output_utf8_bom.csv
PowerShell 7 이상: BOM 없는 UTF-8 강제
Get-Content .\input.csv | Set-Content -Encoding utf8NoBOM .\output_utf8_nobom.csv
대용량 파일에서는 스트리밍 권장
$reader = [System.IO.StreamReader]::new("input.csv", [System.Text.Encoding]::GetEncoding(949)) # 원본이 ANSI(949) 가정
$writer = [System.IO.StreamWriter]::new("output_utf8_nobom.csv", $false, [System.Text.UTF8Encoding]::new($false))
while (($line = $reader.ReadLine()) -ne $null) { $writer.WriteLine($line) }
$reader.Close(); $writer.Close()
방법 C. VBA로 직접 UTF-8 쓰기
엑셀 내부에서 버튼 하나로 CSV를 UTF-8로 내보낼 수 있다.
Option Explicit
Sub ExportCsvUtf8_NoBOM()
Dim fso As Object, ts As Object
Dim p As String, r As Long, c As Long, lastR As Long, lastC As Long
Dim lineStr As String, q As String: q = Chr(34)
Dim ws As Worksheet: Set ws = ActiveSheet
lastR = ws.Cells(ws.Rows.Count,
1).End(xlUp).Row
lastC = ws.Cells(1, ws.Columns.Count).End(xlToLeft).Column
p = ThisWorkbook.Path & "\export_utf8_nobom.csv"
Set fso = CreateObject("ADODB.Stream")
With fso
.Type = 2 ' Text
.Charset = "utf-8"
.Open
' BOM 제거: utf-8로 쓰고 나중에 바이너리 재열어 BOM 3바이트 제거
End With
For r = 1 To lastR
lineStr = ""
For c = 1 To lastC
Dim val As String: val = ws.Cells(r, c).Text
If InStr(val, q) > 0 Then val = Replace(val, q, q & q)
If InStr(val, ",") > 0 Or InStr(val, vbLf) > 0 Or InStr(val, vbCr) > 0 Then
val = q & val & q
End If
If c = 1 Then
lineStr = val
Else
lineStr = lineStr & "," & val
End If
Next c
fso.WriteText lineStr & vbCrLf
Next r
' 임시 파일로 저장
fso.SaveToFile p, 2
fso.Close
' BOM 제거 처리
Dim bin As Object: Set bin = CreateObject("ADODB.Stream")
bin.Type = 1: bin.Open
bin.LoadFromFile p
bin.Position = 3 ' BOM 3바이트 스킵
Dim nobom As Object: Set nobom = CreateObject("ADODB.Stream")
nobom.Type = 1: nobom.Open
bin.CopyTo nobom
nobom.SaveToFile Replace(p, ".csv", "_final.csv"), 2
bin.Close: nobom.Close
MsgBox "완료: " & Replace(p, ".csv", "_final.csv")
End Sub
BOM 포함 vs 무BOM 선택 기준
| 대상 시스템 | 권장 | 이유 |
|---|---|---|
| 대부분의 웹 서비스, 파이썬 판다스 기본 | UTF-8 무BOM | BOM을 헤더로 오인하거나 필드 첫 글자에 특수문자()가 섞이는 문제를 예방한다. |
| 윈도우 메모장, 일부 엑셀 자동감지 | UTF-8 BOM | 파일 오픈 시 문자셋 자동판별에 유리하다. |
| 레거시 ERP/장비 로거 | 사양 확인 필수 | 구현에 따라 BOM 처리 방식이 다르므로 테스트가 필요하다. |
구분자와 지역 설정: 쉼표, 세미콜론, 탭
CSV의 C는 Comma를 의미하지만, 지역설정의 목록 구분 기호 에 따라 엑셀이 세미콜론을 쓰는 경우가 있다. 한국 로캘에서는 보통 쉼표를 사용한다. 데이터에 쉼표가 많아 가독성이 떨어지면 텍스트(탭으로 분리) 형식 또는 탭 구분(\t)으로 내보내고, 대상 시스템이 TSV를 허용하는지 확인한다.
| 형식 | 장점 | 단점 |
|---|---|---|
| CSV(쉼표) | 대부분 시스템 표준 호환 | 데이터 내 쉼표 존재 시 인용·이스케이프 필요 |
| CSV(세미콜론) | 유럽 로캘에서 숫자 쉼표와 충돌 감소 | 일부 파서 기본값과 불일치 |
| TSV(탭) | 필드 내 쉼표·세미콜론 문제 최소화 | 공백·탭 혼동 가능, 일부 도구에서 기본 미지원 |
숫자·날짜·우편번호 보존을 위한 사전 정리
- 우편번호·제품코드 등 앞자리 0 유지가 필요한 열은 내보내기 전 텍스트 형식으로 지정한다.
-
날짜/시간
은 표준 ISO 8601(
YYYY-MM-DD,YYYY-MM-DDTHH:MM:SS)로 변환하여 텍스트로 확정한다. -
줄바꿈
이 있는 셀은 의도된 값인지 점검한다. 엑셀 내부 줄바꿈은 CSV에서
\r\n으로 출력되며 필드가 큰따옴표로 감싸져야 한다.
=TEXT(A2,"yyyy-mm-dd") '날짜 표준화 =TEXT(B2,"0") '앞자리 0 보존 =SUBSTITUTE(C2,CHAR(10)," ") '셀 내부 줄바꿈 제거(필요 시)
검증: 저장 직후 인코딩·필드 확인 체크리스트
| 항목 | 체크 방법 | 합격 기준 |
|---|---|---|
| 인코딩 | 편집기에서 파일 열기 → 상태바/정보 패널 확인 | UTF-8로 표시 |
| BOM 존재 | 파서 첫 필드 값에 특수문자() 여부 확인 | 요구사항과 일치(BOM 포함/무BOM) |
| 구분자 | 한 줄 임의 표본에서 필드 구분 확인 | 의도한 구분자 사용 |
| 인용 규칙 | 쉼표·따옴표·줄바꿈 포함 필드 확인 | 필드 전체 인용, 내부 따옴표 이스케이프 |
| 숫자 형식 | 앞자리 0, 자릿수, 소수점 확인 | 손실 없음 |
자동화 파이프라인: 대량 내보내기와 재현성
PowerShell 배치 처리
# 폴더 내 모든 CSV를 UTF-8 무BOM으로 일괄 변환 (PowerShell 7+) Get-ChildItem -Filter *.csv | ForEach-Object { $in = $_.FullName $out = [System.IO.Path]::ChangeExtension($in, ".utf8.csv") Get-Content $in | Set-Content -Encoding utf8NoBOM $out }
파이썬 판다스로 내보내기
import pandas as pd
df = pd.read_excel("data.xlsx", sheet_name=0)
BOM 포함(일부 윈도우 앱 호환성 ↑)
df.to_csv("export_utf8_bom.csv", index=False, encoding="utf-8-sig")
BOM 없음(웹/리눅스 파이프라인 선호)
df.to_csv("export_utf8_nobom.csv", index=False, encoding="utf-8")
\r\n
, 유닉스는
\n
을 사용한다. 파이썬의
to_csv
는 기본적으로 OS의 EOL을 따른다.
엑셀에서 CSV 열 때 발생하는 오해 방지
CSV를 다시 엑셀로 열면 보이는 형식은 엑셀이 임의로 추론한 결과이다. 앞자리 0 제거, 긴 숫자 자릿수 반올림, 날짜 자동변환 등은 파일 문제라기보다 엑셀의 자동 서식 때문이다. 데이터 품질을 확인하려면 코드 편집기로 텍스트를 확인하거나, 엑셀에서 데이터 > 텍스트/CSV에서 를 사용해 데이터 형식 과 파일 원본 을 수동 지정한다.
프로덕션 투입 전 사양 확인 체크리스트
- 문자셋: UTF-8 with/without BOM 명시 필요하다.
- 구분자: 쉼표/세미콜론/탭 중 요구사항 확인한다.
-
행 끝(EOL):
\r\nvs\n확인한다. - 헤더 행 포함 여부와 컬럼 순서 고정 규칙을 문서화한다.
- 인용 규칙: 줄바꿈·구분자·따옴표 포함 필드 처리 명시한다.
문제 해결: 증상별 원인과 해결
| 증상 | 가능 원인 | 해결 |
|---|---|---|
| 한글이 ????? 로 보임 | ANSI 저장 | CSV UTF-8로 저장하거나 PowerShell/메모장으로 UTF-8 재인코딩 |
| 첫 컬럼에  문자가 붙음 | BOM 포함 | 무BOM으로 재저장 또는 파서의 BOM 처리 옵션 사용 |
| 열 개수가 맞지 않음 | 구분자와 데이터 내 문자 충돌 | 문제 필드 인용(큰따옴표) 및 이스케이프 확인 |
| 앞자리 0 사라짐 | 엑셀 자동 서식 | 텍스트 형식 지정 후 저장 또는 파서에서 문자열로 강제 |
| 긴 숫자 반올림 | 표시 자릿수 제한 | 텍스트로 변환 후 저장, 원본은 문자열로 유지 |
현장 적용 템플릿: 내보내기 전 1분 점검
- 원본 .xlsx 백업 생성 완료하다.
- 텍스트로 유지할 열 포맷 확정하다.
- 날짜/시간 ISO 8601로 변환하다.
- CSV UTF-8로 저장하다.
- 편집기로 열어 인코딩·구분자·인용 규칙 확인하다.
- 대상 시스템에 시험 업로드 후 레코드 카운트·샘플 필드 검증하다.
FAQ
CSV UTF-8로 저장했는데도 웹에서 깨져 보인다. 왜 그런가?
대상 웹 서비스가 업로드 후 서버 내부에서 다른 인코딩으로 다시 해석하거나, 파일의 BOM 여부를 가정하는 경우가 있다. 무BOM/with BOM을 바꿔서 테스트하고, 서비스의 CSV 사양 문서를 확인하여 구분자·인용 규칙까지 일치시키는 것이 중요하다.
엑셀에서 TSV(탭)로 저장하는 것이 더 안전한가?
데이터에 쉼표가 매우 많고 파서가 TSV를 지원한다면 탭이 안전할 수 있다. 다만 많은 시스템이 기본 입력을 CSV로 가정하므로 사양을 먼저 확인해야 한다.
수식 결과만 내보내고 싶다. 어떻게 하나?
내보내기 전 전체 범위를 복사 후 선택하여 붙여넣기 > 값 으로 고정한 뒤 CSV로 저장한다. 또는 파워쿼리/파이썬으로 연산 결과를 생성해 바로 CSV로 기록한다.
대용량 데이터에서 엑셀이 멈춘다. 대안은?
엑셀 대신 파이썬 판다스나 PowerShell 스트리밍으로 직접 CSV를 생성한다. 메모리 사용량과 속도가 유리하다.
열 구분을 세미콜론으로 강제할 수 있나?
엑셀의 지역 설정에 따른 목록 구분 기호를 변경하거나, VBA/파이썬 등으로 원하는 구분자를 직접 기록한다. 대상 시스템이 세미콜론 CSV를 허용하는지 확인해야 한다.