Wie man CSV in Excel korrekt öffnet und speichert | UTF-8 BOM-Unterstützung ohne beschädigte Zeichen
「Beim Öffnen einer aus dem System exportierten CSV-Datei in Excel wurden japanische Zeichen beschädigt」——dieses Problem ist ein tägliches Ärgernis in der Web-Entwicklung, Datenanalyse und Business-Systemen. Die Ursache liegt hauptsächlich in dem Unterschied zwischen UTF-8 und Shift_JIS(CP932) Zeichensätzen. Dieser Artikel erläutert systematisch die Grundursache der Zeichenbeschädigung, die Lösung mit UTF-8-BOM-CSV, Excel-Importverfahren, Implementierungsmethoden in PHP und Python bis zu Problemen mit Zeilenumbruchcodes.
Problem, dass Excel standardmäßig Shift_JIS erwartet
Excel für Windows erkennt die Kodierung automatisch basierend auf den Gebietsschemaeinstellungen des Betriebssystems, wenn Sie CSV-Dateien mit Doppelklick öffnen. In der japanischen Version von Windows ist diese Standard-Kodierung <strong>Shift_JIS (Codepage 932)</strong>.
Wenn Sie eine in UTF-8 gespeicherte CSV-Datei per Doppelklick öffnen, werden Multibyte-Zeichen (wie Japanisch) nicht korrekt interpretiert, was zu Zeichenkodierungsfehlern führt. Dies ist der Grund, warum das Problem 「ein Ingenieur generierte eine UTF-8-CSV in einem Web-System und ein nicht-technischer Mitarbeiter öffnete sie in Excel, was zu Zeichenkodierungsfehlern führte」 wiederholt auftritt.
Wenn wir die Entsprechungsbeziehungen der Zeichenkodierung organisieren, erhalten wir Folgendes.
| Zeichenkodierung | Alias | Handhabung in Excel | Handhabung im Web/Linux |
|---|---|---|---|
| Shift_JIS | CP932、Windows-31J | Standard in der japanischen Version | Legacy. Verwendung nicht empfohlen |
| UTF-8 (ohne BOM) | — | Zeichenverzerrung (alte Version) | Web-Standards |
| Mit UTF-8-BOM | UTF-8 with BOM | Korrekt erkannt | Die BOM kann auch als unerwünschtes Zeichen problematisch sein |
| UTF-16 LE mit BOM | — | Korrekt erkannt | Selten verwendet |
So vermeiden Sie Zeichenverstümmelung in CSV mit UTF-8-BOM
Die BOM (Byte Order Mark) ist eine spezielle Byte-Sequenz, die am Anfang einer Datei hinzugefügt wird und als Signatur zur Identifizierung der Zeichenkodierung einer Textdatei dient. Die UTF-8 BOM besteht aus 3 Bytes: <code>EF BB BF</code> (hexadezimal).
Excel erkennt diese BOM beim Öffnen der Datei und stellt fest, dass「diese Datei in UTF-8 geschrieben wurde」. Dies ist der Grund, warum <strong>die Verwendung von CSV mit UTF-8 BOM beschädigte Zeichen in Excel verhindert</strong>.
Um den Unterschied zwischen UTF-8 mit BOM und UTF-8 ohne BOM zu überprüfen, prüfen Sie die ersten Bytes der Datei mit einem Texteditor oder dem Befehl <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)
Verfahren zum Importieren von 「Daten」→「Textdatei」 in Excel
Um eine UTF-8-CSV-Datei ohne BOM in Excel korrekt zu öffnen, verwenden Sie die Funktion 「Daten importieren」 anstelle von Doppelklick. Die Schritte unterscheiden sich je nach Version, aber in Excel 2016 und neueren Versionen (einschließlich Microsoft 365) können Sie die folgenden Schritte verwenden.
- Starten Sie Excel und öffnen Sie eine neue Arbeitsmappe.
- Klicken Sie auf die Registerkarte 「Daten」 → 「Aus Text oder CSV」.
- Wählen Sie die Ziel-CSV-Datei aus und klicken Sie auf 「インポート」.
- Der Vorschaubildschirm wird angezeigt. Wählen Sie <strong>65001: Unicode (UTF-8)</strong> aus dem Dropdown 「Dateiquelle」.
- Bestätigen Sie, dass das Trennzeichen auf 「Komma」 eingestellt ist, und klicken Sie auf 「Laden」.
Bei Excel 2013 oder älter verwenden Sie 「Daten」→「Externe Daten importieren」→「Textdatei」 und ändern Sie die Zeichenkodierung in Schritt 2 des 「Textdatei-Assistenten」 auf UTF-8 (65001).
Code zum Ausgeben von CSV mit UTF-8 BOM in PHP
Beim Herunterladen einer CSV-Datei aus einem Web-System ist das Generieren einer CSV-Datei mit UTF-8 und BOM mit PHP die einfachste Lösung.
// 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');
Beachten Sie, dass <code>fputcsv()</code> standardmäßig Kommatrennzeichen und Escape mit doppelten Anführungszeichen verwendet. Wenn Sie das Trennzeichen ändern möchten, können Sie es im dritten Argument angeben (Beispiel: Für Tabulatortrennung verwenden Sie <code>"\t"</code>).
Code zur Zeichenkodierungskonvertierung in Python
Python ist praktisch, um die Zeichenkodierung vorhandener CSV-Dateien zu konvertieren oder Daten von Shift_JIS zu UTF-8 zu konvertieren.
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)
Wenn Sie <code>encoding='utf-8-sig'</code> in Python's <code>open()</code> angeben, wird die BOM beim Schreiben automatisch hinzugefügt und beim Lesen automatisch entfernt.
Besonderheiten von Excel für macOS
In Excel für macOS (Microsoft 365 for Mac) gibt es Punkte, in denen sich das Verhalten von der Windows-Version unterscheidet.
- <strong>CSV mit UTF-8 BOM</strong>: Öffnet sich korrekt mit Doppelklick in Excel auf macOS (ab relativ neuen Versionen).
- <strong>Alte Versionen (wie Excel 2016 für Mac)</strong>: Es kann zu Zeichenverstümmelung kommen, selbst mit UTF-8 BOM. Verwenden Sie in diesem Fall 「Daten importieren」.
- <strong>Wählen Sie CSV in 「Speichern unter」</strong>:In der macOS-Version wird möglicherweise ohne UTF-8 BOM gespeichert. Die an die Windows-Umgebung übergebene CSV muss überprüft werden.
- <strong>Gemischte Verwendung mit Numbers.app</strong>: Numbers auf macOS behandelt UTF-8 als Standard, aber die Kompatibilität mit Excel erfordert Vorsicht.
Problem mit Zeilenumbruchcode (CRLF vs LF)
Neben der falschen Zeichenkodierung in CSV können auch Unterschiede in den Zeilenumbruchcodes ein Problem darstellen.
| Zeilenumbruchcode | Bytefolge | Hauptumgebungen | Umgang mit CSV |
|---|---|---|---|
| CRLF | 0D 0A |
Windows、HTTP | In RFC 4180 definierter Standard |
| LF | 0A |
Linux-, macOS- und Git-Standard | In den meisten Fällen funktioniert es auch in Excel |
| CR | 0D |
Älteres macOS (9 oder früher) | Kann nur bei älteren Excel-Versionen ein Problem sein |
Die RFC 4180, die Standard-CSV-Spezifikation, schreibt CRLF vor, aber modernes Excel verarbeitet CSVs mit nur LF ohne Probleme. Wenn ein CSV jedoch Zeilenumbrüche innerhalb von Feldern enthält, wird der Umgang mit dem Zeilenumbruchcode wichtig. PHPs <code>fputcsv()</code> verwendet standardmäßig LF, aber wenn die Kompatibilität mit Windows-Umgebungen wichtig ist, sollten Sie eine Konvertierung mit <code>str_replace("\n", "\r\n", $output)</code> nach der Ausgabe in Betracht ziehen.
// 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;
}
Zusammenfassung: Best Practices für CSV-Verteilung ohne Zeichenverstümmelung
- Exportieren Sie CSV mit UTF-8 BOM, wenn Sie es an Excel-Benutzer verteilen
- In PHP fügen Sie BOM am Anfang mit <code>fputs($output, "\xEF\xBB\xBF")</code> hinzu
- <code>encoding='utf-8-sig'</code> in Python angeben
- Verwenden Sie die Befehle <code>chardet</code> oder <code>file</code>, um die Zeichenkodierung der empfangenen CSV zu überprüfen
- Wenn Sie CSV in UTF-8 ohne BOM an Excel-Benutzer weitergeben, leiten Sie sie zum Verfahren「Daten importieren」
- CRLF ist der RFC-Standard für Zeilenumbruchcodes, aber modernes Excel akzeptiert auch LF
- Da Excel für macOS unterschiedliches Verhalten aufweisen kann, wird empfohlen, die Funktionalität auf der Empfängerseite zu überprüfen
Testdatei zur Verwendung in diesem Artikel
- <a href="/ja/files/encoding/" class="text-primary-600 dark:text-primary-400 hover:underline">Zeichenkodierungs-Testdateiliste</a> — Beispiele verschiedener Kodierungen wie UTF-8 mit/ohne BOM und Shift_JIS
- <a href="/ja/files/csv/" class="text-primary-600 dark:text-primary-400 hover:underline">CSV-Testdateiliste</a> — Beispiele mit Kombinationen von Zeilenumbruchcodes, Zeichenkodierung und BOM-Präsenz/Abwesenheit
- <a href="/ja/files/newline/" class="text-primary-600 dark:text-primary-400 hover:underline">Testdateien für Zeilenumbruchcodes</a> — Überprüfung jedes Musters CRLF / LF / CR
Verwandte Artikel
- <a href="/ja/blog/csv-encoding-trouble-guide/" class="text-primary-600 dark:text-primary-400 hover:underline">CSV-Kodierungsprobleme vollständig lösen! Grundwissen zu Zeichencodierung, BOM und Zeilenumbrüchen</a>
- <a href="/ja/blog/file-format-quick-reference/" class="text-primary-600 dark:text-primary-400 hover:underline">Schnellreferenz für Dateiformate für Entwickler</a>
- <a href="/ja/blog/base64-size-increase/" class="text-primary-600 dark:text-primary-400 hover:underline">Warum Base64-Kodierung die Dateigröße um 33% erhöht</a>