Saltar al contenido

Cómo abrir y guardar correctamente CSV en Excel | Soporte UTF-8 BOM para evitar corrupción de caracteres

Categoría: Procesamiento de datos / Excel

「Cuando exporté un archivo CSV del sistema y lo abrí en Excel, los caracteres japoneses se corrompieron」——este problema ocurre diariamente en el campo del desarrollo web, análisis de datos y sistemas empresariales. La causa raíz suele ser la diferencia en la codificación de caracteres entre UTF-8 y Shift_JIS (CP932). Este artículo explica sistemáticamente la causa fundamental de la corrupción de caracteres, soluciones mediante CSV con BOM UTF-8, procedimientos de importación en Excel, métodos de implementación en PHP y Python, y problemas de códigos de línea.

Flujo de resolución de mojibake en Excel y CSV UTF-8 CSV Salida web BOM? EF BB BF Mojibake 縺ゅ>縺・▲ ... Visualización correcta あいうえお No Yes Soluciones 1. Salida UTF-8 con BOM 2. Usar asistente de importación de Excel 3. Convertir a Shift_JIS (CP932) (heredado) Excel Mac BOM inestable — UTF-8 LF recomendado
Fig 1: Detección y resolución de mojibake al abrir CSV UTF-8 en Excel

Problema: Excel espera Shift_JIS de forma predeterminada

Al abrir archivos CSV con doble clic en Excel para Windows, la codificación se detecta automáticamente según la configuración de idioma del SO. En Windows japonés, esta codificación predeterminada es Shift_JIS (página de códigos 932).

Por esta razón, cuando abre directamente un CSV guardado en UTF-8 haciendo doble clic, los caracteres multibyte (como el japonés) no se interpretan correctamente, lo que resulta en texto corrupto. Esta es la razón por la que el problema de "un no ingeniero abriendo un CSV UTF-8 generado por un ingeniero en un sistema web con Excel y encontrando texto corrupto" ocurre repetidamente.

La correspondencia de codificaciones de caracteres se puede organizar de la siguiente manera.

Codificación de Caracteres Alias Manejo en Excel Manejo en Web y Linux
Shift_JIS CP932、Windows-31J Estándar en la versión en japonés Heredado. No se recomienda su uso
UTF-8 (sin BOM) Corrupción de caracteres (versión anterior) Estándares web
UTF-8 con BOM UTF-8 with BOM Se reconoce correctamente La BOM puede causar problemas como caracteres adicionales
UTF-16 LE con BOM Se reconoce correctamente Raramente utilizado

Cómo evitar problemas de codificación de caracteres con CSV UTF-8 con BOM

La BOM (Byte Order Mark) es una secuencia especial de bytes añadida al principio de un archivo, que sirve como firma para identificar la codificación de caracteres de un archivo de texto. La BOM UTF-8 son 3 bytes: EF BB BF (en hexadecimal).

Excel detecta este BOM al abrir un archivo y determina "este archivo está escrito en UTF-8". Esta es la razón por la que usar CSV UTF-8 con BOM evita texto corrupto en Excel.

Para verificar la diferencia entre UTF-8 con BOM y UTF-8 sin BOM, comprueba los bytes del encabezado del archivo usando un editor de texto o el comando hexdump.

# 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)

Pasos para importar desde "Datos" → "Archivo de texto" en Excel

Para abrir archivos CSV UTF-8 sin BOM correctamente en Excel, usa la función "Importar datos" en lugar de hacer doble clic. Los pasos varían según la versión, pero el siguiente procedimiento funciona para Excel 2016 y posteriores (incluido Microsoft 365).

  1. Inicie Excel y abra un nuevo libro de trabajo.
  2. Haga clic en la pestaña 「Datos」 → 「Desde texto o CSV」.
  3. Selecciona el archivo CSV objetivo y haz clic en Importar.
  4. Se muestra una pantalla de vista previa. Seleccione 65001: Unicode (UTF-8) en el menú desplegable "Origen del archivo".
  5. Verifique que el delimitador esté configurado en 「coma」 y haga clic en 「Cargar」.

Para Excel 2013 y anteriores, use "Datos" → "Importar datos externos" → "Archivo de texto", y cambie la codificación de caracteres a UTF-8 (65001) en el paso 2 del "Asistente de archivos de texto".

Código para generar CSV con BOM UTF-8 en PHP

Cuando se permite descargar un CSV desde un sistema web, la solución más simple es generar un CSV UTF-8 con BOM en PHP.

// 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');

Tenga en cuenta que fputcsv() usa separadores de comas y escape con comillas dobles por defecto. Si desea cambiar el delimitador, puede especificarlo con el tercer argumento (por ejemplo, para valores separados por tabulación use "\t").

Código de conversión de codificación de caracteres en Python

Python es conveniente para convertir la codificación de caracteres de archivos CSV existentes o convertir datos recibidos en Shift_JIS a UTF-8.

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)

Al especificar encoding='utf-8-sig' en open() de Python, la BOM se añade automáticamente al escribir y se elimina automáticamente al leer.

Consideraciones de Excel para macOS

Excel para macOS (Microsoft 365 for Mac) tiene diferencias de comportamiento en comparación con la versión de Windows.

  • CSV con BOM UTF-8: Se abre correctamente con doble clic incluso en Excel para macOS (a partir de versiones relativamente recientes).
  • Versiones antiguas (Excel 2016 para Mac, etc.): La corrupción de caracteres puede ocurrir incluso con UTF-8 BOM. En tales casos, usa la función "Importar datos"
  • Seleccionar CSV en "Guardar como": En versiones de macOS, puede guardarse sin BOM UTF-8. Los archivos CSV pasados a entornos Windows requieren reverificación.
  • Uso mixto con Numbers.app: Numbers en macOS trata UTF-8 como estándar, pero la compatibilidad con Excel requiere precaución.

Problemas de Código de Salto de Línea (CRLF vs LF)

Junto con caracteres garrapateados en CSV, las diferencias en los finales de línea también pueden ser problemáticas.

Código de Salto de Línea Cadena de bytes Entornos principales Manejo en CSV
CRLF 0D 0A Windows、HTTP Estándar definido en RFC 4180
LF 0A Predeterminado de Linux, macOS, Git Funciona en la mayoría de los casos con Excel
CR 0D macOS antiguo (9 y anteriores) Solo puede ser un problema con versiones antiguas de Excel

Aunque RFC 4180, la especificación estándar para CSV, especifica CRLF, Excel moderno maneja archivos CSV solo con LF sin problemas. Sin embargo, cuando CSV contiene saltos de línea dentro de campos, el manejo de los finales de línea se vuelve importante. El fputcsv() de PHP usa LF de manera predeterminada, pero si la compatibilidad con Windows es importante, considera convertir con str_replace("\n", "\r\n", $output) después de la salida.

// 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;
}

Resumen: Mejores prácticas para distribuir archivos CSV sin corrupción de caracteres

  • Exportar CSV con UTF-8 BOM al distribuir a usuarios de Excel
  • En PHP, agregue BOM al principio usando fputs($output, "\xEF\xBB\xBF")
  • En Python, especifique encoding='utf-8-sig'
  • Para verificar la codificación de caracteres de un CSV recibido, utiliza el comando chardet o file
  • Al proporcionar CSV UTF-8 sin BOM a usuarios de Excel, guíelos a través del proceso "Importar datos".
  • CRLF es el estándar RFC para códigos de salto de línea, pero Excel moderno también acepta LF
  • Excel para macOS puede tener un comportamiento diferente; se recomienda verificar el funcionamiento en el lado receptor

Archivos de prueba para este artículo

❓ Preguntas frecuentes

¿Por qué Excel me estropea el CSV?
En Windows, Excel lee los CSV como Shift_JIS por defecto, así que un archivo UTF-8 sale ilegible. Guardarlo en UTF-8 con BOM lo soluciona.
¿Qué es un BOM (Byte Order Mark)?
Un marcador de tres bytes (EF BB BF) al inicio del archivo que indica al software que el contenido es UTF-8. Excel lo necesita para reconocerlo bien.
¿Cómo abro correctamente un CSV en Excel para macOS?
Usa la importación de texto de la pestaña Datos y elige explícitamente UTF-8 como codificación; es la vía fiable también en macOS.

Preguntas frecuentes

¿Por qué se corrompe el CSV al abrirlo en Excel?

Excel lee los archivos como Shift_JIS (entorno Windows) por defecto, lo que causa corrupción en CSV UTF-8. Se resuelve guardando con UTF-8 BOM.

¿Qué es BOM (Byte Order Mark)?

Una marca de 3 bytes (EF BB BF) agregada al inicio del archivo indica al software que es UTF-8. Esto es necesario para que Excel reconozca correctamente UTF-8.

¿Cómo abrir correctamente CSV en Excel para macOS?

Incluso en Excel para macOS, es confiable usar la importación de archivos de texto desde la pestaña Datos y especificar UTF-8 como la codificación de caracteres.