콘텐츠로 건너뛰기

Excel에서 CSV를 올바르게 열고 저장하는 방법|문자 깨짐 방지 UTF-8 BOM 대응

카테고리: 데이터 처리·Excel
이 기사는 현재 일본어로만 제공됩니다. 번역본은 순차적으로 공개될 예정입니다.

「시스템에서 내보낸 CSV 파일을 Excel로 열었는데 일본어가 깨졌다」——이 문제는 웹 개발, 데이터 분석, 업무 시스템 현장에서 일상적으로 발생하는 문제입니다. 대부분의 원인은 UTF-8과 Shift_JIS(CP932)의 문자 인코딩 차이에 있습니다. 본 기사에서는 문자 깨짐의 근본 원인부터 시작하여 UTF-8 BOM이 포함된 CSV를 이용한 해결 방법, Excel의 가져오기 절차, PHP·Python 구현 방법, 줄바꿈 코드 문제까지 체계적으로 설명합니다.

Excel와 CSV 문자 깨짐 해결 흐름 UTF-8 CSV 웹 출력 BOM? EF BB BF 문자 깨짐 縺ゅ>縺・▲ ... 정상 표시 あいうえお No Yes 해결 방법 1. UTF-8 BOM 포함 출력 2. Excel 데이터 가져오기 마법사 사용 3. Shift_JIS (CP932)로 변환 출력 (레거시) Mac Excel은 BOM 인식 불안정 — UTF-8 LF 권장
그림 1: UTF-8 CSV를 Excel에서 열 때의 문자 깨짐 판정과 해결 경로

Excel이 기본적으로 Shift_JIS를 기대하는 문제

Windows 버전의 Excel에서 CSV 파일을 더블클릭으로 열 때, OS의 로케일 설정을 기반으로 인코딩을 자동으로 감지합니다. 일본어 Windows에서는 이 기본 인코딩이 <strong>Shift_JIS(코드페이지 932)</strong>입니다.

따라서 UTF-8로 저장된 CSV를 더블클릭으로 그대로 열면 멀티바이트 문자(일본어 등)가 올바르게 해석되지 않아 문자가 깨집니다. 「엔지니어가 웹 시스템에서 생성한 UTF-8 CSV를 엔지니어가 아닌 담당자가 Excel로 열었을 때 문자가 깨진다」는 문제가 반복적으로 발생하는 이유가 바로 이것입니다.

문자 인코딩의 대응 관계를 정리하면 다음과 같습니다.

문자 인코딩 별칭 Excel에서의 처리 웹·Linux에서의 취급
Shift_JIS CP932、Windows-31J 일본어 버전에서 표준 레거시. 사용 비권장
UTF-8 (BOM 없음) 문자가 깨짐 (이전 버전) 웹 표준
UTF-8 BOM 포함 UTF-8 with BOM 올바르게 인식됨 BOM이 불필요한 문자로 문제가 될 수 있음
UTF-16 LE BOM 포함 올바르게 인식됨 잘 사용되지 않음

UTF-8 BOM 포함 CSV에서 문자 깨짐 방지 방법

BOM(Byte Order Mark)은 파일의 시작에 추가되는 특수한 바이트 시퀀스로, 텍스트 파일의 문자 코드를 식별하기 위한 시그니처입니다. UTF-8 BOM은 <code>EF BB BF</code>(16진수)의 3바이트입니다.

Excel은 파일을 열 때 이 BOM을 감지하고 "이 파일은 UTF-8로 작성되었다"고 판단합니다. 이것이 <strong>BOM이 있는 UTF-8 CSV를 사용하면 Excel에서 문자 깨짐이 없는</strong> 이유입니다.

BOM이 있는 UTF-8과 BOM이 없는 UTF-8의 차이를 확인하려면, 텍스트 에디터나 <code>hexdump</code> 명령으로 파일의 처음 바이트를 확인합니다.

# Linux / macOS での確認
hexdump -C sample.csv | head -1

# BOM なし UTF-8 の出力例:
# 00000000  e5 90 8d e5 89 8d 2c e5  ...
# BOM 付き UTF-8 の出力例:
# 00000000  ef bb bf e5 90 8d e5 89  ...(先頭に ef bb bf)

Excel에서 "데이터" → "텍스트 파일"에서 가져오기 단계

BOM이 없는 UTF-8 CSV 파일을 Excel에서 올바르게 열려면, 더블 클릭하지 말고 "데이터 가져오기" 기능을 사용합니다. 버전에 따라 단계가 다르지만, Excel 2016 이상(Microsoft 365 포함)에서는 다음 절차를 사용할 수 있습니다.

  1. Excel을 시작하고 새 통합 문서를 엽니다.
  2. 「데이터」탭 → 「텍스트 또는 CSV에서」를 클릭합니다.
  3. 대상 CSV 파일을 선택하고 「Import」를 클릭합니다.
  4. 미리보기 화면이 표시됩니다. "파일 원본" 드롭다운에서 <strong>65001: Unicode (UTF-8)</strong>을 선택합니다.
  5. 구분 문자가 「쉼표」로 설정되어 있는지 확인한 후 「로드」를 클릭합니다.

Excel 2013 이전의 경우 "데이터" → "외부 데이터 가져오기" → "텍스트 파일"을 사용하고, "텍스트 파일 마법사"의 2단계에서 문자 인코딩을 UTF-8(65001)로 변경합니다.

PHP에서 UTF-8 BOM이 있는 CSV를 출력하는 코드

웹 시스템에서 CSV를 다운로드하도록 할 경우, PHP에서 BOM이 있는 UTF-8 CSV를 출력하는 것이 가장 간단한 해결 방법입니다.

// UTF-8 BOM 付き CSV のダウンロード出力
function outputCsvWithBom(array $headers, array $rows, string $filename = 'export.csv'): void
{
    // キャッシュ無効化・ダウンロードヘッダーを設定
    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');
    header('Cache-Control: no-cache, no-store, must-revalidate');

    $output = fopen('php://output', 'w');

    // UTF-8 BOM を出力(EF BB BF)
    fputs($output, "\xEF\xBB\xBF");

    // ヘッダー行を出力
    fputcsv($output, $headers);

    // データ行を出力
    foreach ($rows as $row) {
        fputcsv($output, $row);
    }

    fclose($output);
    exit;
}

// 使用例
$headers = ['名前', 'メールアドレス', '登録日'];
$rows = [
    ['山田 太郎', 'taro@example.com', '2026-04-14'],
    ['鈴木 花子', 'hanako@example.com', '2026-04-13'],
];

outputCsvWithBom($headers, $rows, 'users_' . date('Ymd') . '.csv');

<code>fputcsv()</code>는 기본적으로 쉼표 구분과 큰따옴표 이스케이프를 사용합니다. 구분 기호를 변경하려면 세 번째 인수로 지정할 수 있습니다(예: 탭 구분은 <code>"\t"</code>).

Python에서의 문자 인코딩 변환 코드

기존 CSV 파일의 문자 인코딩을 변환하거나 Shift_JIS로 전달된 데이터를 UTF-8로 변환할 때 Python이 편리합니다.

import csv
import codecs

# BOM なし UTF-8 → BOM 付き UTF-8 に変換して保存
def add_bom_to_utf8_csv(input_path: str, output_path: str) -> None:
    with open(input_path, 'r', encoding='utf-8') as infile:
        content = infile.read()

    with open(output_path, 'w', encoding='utf-8-sig') as outfile:
        # 'utf-8-sig' は自動的に BOM を付加する
        outfile.write(content)


# Shift_JIS CSV → UTF-8 BOM 付き CSV に変換
def convert_sjis_to_utf8_bom(input_path: str, output_path: str) -> None:
    with open(input_path, 'r', encoding='shift_jis', errors='replace') as infile:
        rows = list(csv.reader(infile))

    with open(output_path, 'w', encoding='utf-8-sig', newline='') as outfile:
        writer = csv.writer(outfile)
        writer.writerows(rows)


# 文字コードを自動検出して変換(chardet を使用)
# pip install chardet
import chardet

def detect_and_convert(input_path: str, output_path: str) -> None:
    with open(input_path, 'rb') as f:
        raw_data = f.read()

    detected = chardet.detect(raw_data)
    encoding = detected['encoding'] or 'utf-8'
    print(f'検出した文字コード: {encoding}(信頼度: {detected["confidence"]*100:.0f}%)')

    content = raw_data.decode(encoding, errors='replace')

    with open(output_path, 'w', encoding='utf-8-sig', newline='') as outfile:
        outfile.write(content)

Python의 <code>open()</code>에서 <code>encoding='utf-8-sig'</code>를 지정하면 쓰기 시 BOM이 자동으로 추가되고 읽기 시 BOM이 자동으로 제거됩니다.

macOS 버전 Excel의 주의점

macOS 버전 Excel (Microsoft 365 for Mac)은 Windows 버전과 동작이 다른 부분이 있습니다.

  • <strong>UTF-8 BOM이 있는 CSV</strong>: macOS 버전 Excel에서도 더블클릭으로 올바르게 열립니다 (비교적 최신 버전부터).
  • <strong>구형 버전(Excel 2016 for Mac 등)</strong>: UTF-8 BOM이 있어도 문자 깨짐이 발생할 수 있습니다. 이 경우 "데이터 가져오기"를 사용하세요
  • <strong>"다른 이름으로 저장"에서 CSV 선택</strong>: macOS 버전에서는 UTF-8 BOM 없이 저장될 수 있습니다. Windows 환경으로 전달하는 CSV는 재확인이 필요합니다.
  • <strong>Numbers.app과의 혼용</strong>: macOS의 Numbers는 UTF-8을 표준으로 취급하지만 Excel과의 호환성에 주의가 필요합니다.

줄 바꿈 코드 문제 (<code>CRLF</code> vs <code>LF</code>)

CSV의 문자 깨짐과 함께 줄바꿈 코드의 차이도 문제가 될 수 있습니다.

줄 바꿈 코드 바이트 열 주요 환경 CSV에서의 처리
CRLF 0D 0A Windows、HTTP RFC 4180에서 정의된 표준
LF 0A Linux, macOS, Git 기본값 대부분의 경우 Excel에서도 작동함
CR 0D 구형 macOS (9 이전) 오래된 Excel에서만 문제가 될 수 있습니다

CSV의 표준 사양인 RFC 4180에서는 CRLF가 규정되어 있지만, 현대의 Excel은 LF만 있는 CSV도 문제없이 처리합니다. 그러나 필드 내에 줄바꿈을 포함하는 CSV에서는 줄바꿈 코드의 처리가 중요해집니다. PHP의 <code>fputcsv()</code>는 기본적으로 LF를 사용하지만, Windows 환경과의 호환성을 중시하는 경우 출력 후 <code>str_replace("\n", "\r\n", $output)</code>로 변환하는 것을 고려해 보세요.

// PHP で CRLF 改行の CSV を出力する方法
function outputCsvCrlfWithBom(array $headers, array $rows, string $filename = 'export.csv'): void
{
    header('Content-Type: text/csv; charset=UTF-8');
    header('Content-Disposition: attachment; filename="' . $filename . '"');

    // 一旦バッファに書き出して CRLF に変換する
    ob_start();
    $output = fopen('php://output', 'w');
    fputs($output, "\xEF\xBB\xBF");
    fputcsv($output, $headers);
    foreach ($rows as $row) {
        fputcsv($output, $row);
    }
    fclose($output);
    $csv = ob_get_clean();

    // LF を CRLF に変換(すでに CRLF になっているものは除外)
    $csv = str_replace(["\r\n", "\n"], "\r\n", $csv);

    echo $csv;
    exit;
}

요약: 문자 깨짐이 없는 CSV 배포의 모범 사례

  • Excel 사용자에게 배포하는 CSV는 UTF-8 BOM 포함하여 출력
  • PHP에서는 <code>fputs($output, "\xEF\xBB\xBF")</code>로 BOM을 맨 앞에 추가합니다
  • Python에서 <code>encoding='utf-8-sig'</code>를 지정합니다.
  • 받은 CSV의 문자 인코딩을 확인하려면 <code>chardet</code> 또는 <code>file</code> 명령을 사용하세요
  • Excel 사용자에게 BOM 없는 UTF-8 CSV를 제공할 때는 "데이터 가져오기" 프로세스를 안내합니다.
  • 줄 바꿈 코드는 <code>CRLF</code>가 RFC 표준이지만, 현대의 Excel은 <code>LF</code>도 허용합니다.
  • macOS 버전 Excel은 동작이 다를 수 있으므로 수신 측에서의 동작 확인을 권장합니다

이 기사에서 사용할 수 있는 테스트 파일

  • <a href="/ja/files/encoding/" class="text-primary-600 dark:text-primary-400 hover:underline">문자 인코딩 테스트 파일 목록</a> — UTF-8 BOM 포함/미포함, Shift_JIS 등 다양한 인코딩 샘플
  • <a href="/ja/files/csv/" class="text-primary-600 dark:text-primary-400 hover:underline">테스트용 CSV 파일 목록</a> — 줄바꿈 코드·문자 코드·BOM 유무의 조합 샘플
  • <a href="/ja/files/newline/" class="text-primary-600 dark:text-primary-400 hover:underline">줄바꿈 코드 테스트 파일 목록</a> — CRLF / LF / CR 각 패턴 확인

관련 기사

  • <a href="/ja/blog/csv-encoding-trouble-guide/" class="text-primary-600 dark:text-primary-400 hover:underline">CSV 문자 인코딩 문제 완전히 해결하기! 문자 코드, BOM, 줄 바꿈의 기초 지식</a>
  • <a href="/ja/blog/file-format-quick-reference/" class="text-primary-600 dark:text-primary-400 hover:underline">개발자를 위한 파일 형식 빠른 참조</a>
  • <a href="/ja/blog/base64-size-increase/" class="text-primary-600 dark:text-primary-400 hover:underline">Base64 인코딩이 파일 크기를 33% 증가시키는 이유</a>

자주 묻는 질문

Excel에서 CSV를 열면 문자가 깨지는 이유는?

Excel은 기본적으로 Shift_JIS(Windows 환경)로 읽기 때문에 UTF-8 CSV가 문자화됩니다. UTF-8 BOM을 포함하여 저장하면 해결됩니다.

BOM(Byte Order Mark)이란 무엇입니까?

파일의 맨 앞에 붙는 3바이트 마크(EF BB BF)는 소프트웨어에 UTF-8임을 알립니다. Excel이 UTF-8을 올바르게 인식하기 위해 필요합니다.

macOS 버전 Excel에서 CSV를 올바르게 여는 방법은?

macOS 버전 Excel에서도 데이터 탭에서 텍스트 파일 가져오기를 사용하여 문자 코드에 UTF-8을 지정하여 읽는 것이 확실합니다.