CSV 파일의 한글이 깨질 때: 저장 방식부터 확인하세요

같은 표를 UTF-8, BOM을 넣은 UTF-8, CP949로 저장했습니다. 예제3개로 한글 깨짐의 원인과 다시 불러오는 순서를 확인하세요.

뒤로가기

깨진 상태로 저장하기 전에 원본을 남기세요

CSV를 열었는데 숫자는 읽히고 한글만 이상한 기호로 보일 때가 있습니다. 먼저 창을 닫고 원본의 복사본을 만드세요. 잘못 읽힌 글자를 그대로 저장하면, 처음 파일에 있던 문자 정보를 되찾기 어려워질 수 있습니다.

CSV는 행과 열을 쉼표 같은 구분자로 나누어 저장하는 텍스트 파일입니다. 엑셀에서 열 수 있지만, 글꼴이나 셀 색까지 담는 엑셀 통합 문서와는 다릅니다. 또 확장자가 .csv라는 사실만으로 한글을 어떤 방식으로 저장했는지는 알 수 없습니다.

여기서 인코딩은 문자를 파일의 숫자 데이터로 바꾸는 규칙입니다. 저장할 때 쓴 규칙과 읽을 때 고른 규칙이 다르면 한글이 깨질 수 있습니다.

같은 표를 3가지 방식으로 저장했습니다

실제 개인정보가 없는 작은 표를 만들었습니다. 마지막 메모에는 쉼표도 넣었습니다. 정상적으로 읽으면 아래처럼 머리글1행과 데이터2행이 나옵니다.

항목 수량 메모
공책 12 가나다
연필 3 쉼표, 포함
예제 파일 저장 방식 실제 파일 크기
UTF-8 CSV UTF-8 70바이트
BOM을 넣은 UTF-8 CSV UTF-8 + 시작 표시 73바이트
CP949 CSV CP949 53바이트

세 파일을 각각 올바른 방식으로 읽으면 같은 표가 됩니다. CP949는 한국어 환경에서 사용돼 온 문자 저장 방식입니다. UTF-8은 여러 언어의 문자를 표현할 수 있는 방식입니다. 어느 쪽이든 파일을 만든 쪽과 읽는 쪽의 규칙을 맞춰야 합니다.

BOM은 파일 시작에 붙이는 표시입니다. 위 UTF-8 예제에서는 표시를 넣었을 때 정확히 3바이트가 늘었습니다. Python의 utf-8-sig 방식은 이 표시를 붙여 저장하고 읽을 때는 표시를 제거합니다. Python의 UTF-8 BOM 설명

한글 깨짐을 이렇게 재현했습니다

CP949 파일을 UTF-8 규칙으로 읽고, 해석할 수 없는 부분을 대체 문자로 표시하도록 했습니다. 실제 첫 행은 다음처럼 나왔습니다.

�׸�,����,�޸�

이것은 Excel 화면을 찍은 것이 아니라 Python으로 잘못된 읽기 조건을 만든 결과입니다. 앱마다 오류 처리 방식이 다르므로 실제 화면에는 다른 기호가 보이거나 오류가 날 수 있습니다.

원본 CP949 파일을 CP949로 다시 읽었을 때는 항목,수량,메모가 돌아왔습니다. 이 실험에서는 파일이 망가진 것이 아니라 읽는 규칙이 달랐던 것입니다. 반대로 원본 자체가 이미 물음표로 덮어써졌다면 규칙을 바꾸는 것만으로 복원되지 않을 수 있습니다.

Excel에서 다시 불러오는 순서

Microsoft는 BOM이 들어 있는 UTF-8 CSV를 일반적으로 열 수 있다고 안내합니다. BOM이 없는 파일은 데이터 → 데이터 가져오기 → 파일에서 → 텍스트/CSV로 가져오는 방법을 제시합니다. Microsoft의 UTF-8 CSV 안내

  1. 원본을 복사하고 빈 통합 문서에서 시작하세요.
  2. 텍스트/CSV 가져오기에서 복사한 파일을 선택하세요.
  3. 문자 저장 방식을 고를 수 있다면 파일을 만든 쪽의 안내와 맞추세요. UTF-8 파일이면 UTF-8을 선택합니다.
  4. 미리보기에서 한글과 열 구분을 확인하세요. 처음부터 전체 표를 수정하지 말고 머리글과 메모1개부터 보세요.
  5. 올바르게 읽힌 것을 확인한 뒤 새 이름으로 저장하세요.

메뉴 구성과 선택 항목은 Excel 버전·운영체제에 따라 달라집니다. 이 글에서는 Excel의 각 버전을 직접 실행해 비교하지 않았습니다. 가져오기 경로는 공식 안내를, 저장 방식의 차이는 위 파일 실험을 근거로 설명했습니다.

저장 방식을 모른다면 파일을 보낸 사람이나 내보내기 화면의 안내부터 확인하세요. UTF-8이 아닐 수 있다는 이유만으로 모든 파일을 CP949로 저장할 필요는 없습니다. BOM을 요구하거나 허용하지 않는 서비스도 있을 수 있으므로 최종 제출 규격을 따르세요.

한글은 정상인데 표가 이상하다면

한글은 맞는데 한 행이 셀1개에 들어간다면 구분자 설정을 확인하세요. 메모의 쉼표 때문에 열이 늘어난다면 따옴표로 감싼 값을 처리하는지도 확인해야 합니다. 이 예제의 마지막 메모는 파일 안에서 "쉼표, 포함"으로 저장했습니다.

전화번호나 코드의 앞자리0이 사라지는 문제는 문자 깨짐과 다릅니다. 한글을 바로잡은 뒤에도 열의 값이 원본과 같은지 별도로 확인하세요. 다음 세 가지를 점검하면 다시 저장할 때 생기는 실수를 줄일 수 있습니다.

  • 머리글과 한글 메모가 정상적으로 읽히는가.
  • 데이터 행과 열의 수가 원본과 같은가.
  • 숫자처럼 보이는 코드나 메모의 쉼표가 그대로 남아 있는가.

예제의 검증 범위

2026년10월4일에 Python 표준 라이브러리로 예제를 만들었습니다. 각 파일을 해당 인코딩으로 다시 읽은 뒤 머리글과 데이터가 처음 표와 일치하는지 검사했습니다. 줄바꿈과 구분자는 모두 같게 유지했습니다. 파일 크기 차이는 이 작은 예제의 결과이며 저장 방식의 우열을 뜻하지 않습니다.

측정값과 잘못 읽은 결과를 함께 제공합니다. 생성 코드는 저장소의 scripts/generate_blog_data_examples.py에 있습니다.