
CSV の RFC 4180 と Excel の独自仕様 — なぜ CSV は壊れるのか
「CSV で出力してください」と簡単に言われるものの、実際に動くシステムから出した CSV が Excel で開くと文字化けしたり、セルが崩れる経験は誰しもあるはず。その原因の多くは、IETF の RFC 4180 (2005) と Excel の歴史的な独自実装の差にあります。本記事では一次資料を引きながら、4つの主要トラブルと実務的な対処を整理します。
RFC 4180 の厳密仕様(2005年)
IETF 情報 RFC 4180 "Common Format and MIME Type for Comma-Separated Values (CSV) Files" は、CSV の最低限の仕様を定めた文書です。要点は以下の ABNF で表現されます:
file = [header CRLF] record *(CRLF record) [CRLF]
header = name *(COMMA name)
record = field *(COMMA field)
field = (escaped / non-escaped)
escaped = DQUOTE *(TEXTDATA / COMMA / CR / LF / 2DQUOTE) DQUOTE
non-escaped = *TEXTDATA
COMMA = %x2C
CR = %x0D
DQUOTE = %x22
LF = %x0A
CRLF = CR LF
TEXTDATA = %x20-21 / %x23-2B / %x2D-7E
重要ポイント:
- 改行は CRLF (\r\n) 必須
- ダブルクォートで囲んだフィールド内なら カンマ・CR・LF・ダブルクォート を含められる
- フィールド内のダブルクォートは 2つ重ね("")でエスケープ
- 文字コードは明記されていない (USASCII が前提)
つまり RFC 4180 は「USASCII + CRLF + 最小限のエスケープ規則」しか定めておらず、日本語やマルチバイト文字についての言及が一切ないのが日本の実務で混乱の種になります。
トラブル1: Excel で開くと文字化け (BOM 問題)
Excel (Windows 版) は、CSV を開くとき以下の順でエンコーディングを判定します:
- UTF-8 BOM (0xEF 0xBB 0xBF) があれば UTF-8 と判断
- BOM がなければ システム既定コードページ (日本語環境では Shift-JIS / CP932)
つまり UTF-8 で日本語を出した CSV に BOM がないと、Excel は Shift-JIS として解釈しようとして文字化けします。
# NG: UTF-8, BOM なし → Excel で文字化け
printf '氏名,年齢\n田中,30\n' > users.csv
# OK: UTF-8 BOM 付き → Excel で正しく開ける
printf '\xef\xbb\xbf氏名,年齢\n田中,30\n' > users_bom.csv
対処の実務ベストプラクティス:
- 日本語を含む CSV は常に UTF-8 BOM 付きで出力
- BOM を嫌うシステム (Python の pandas デフォルト読み込み等) 向けにはオプションで切替できる API を提供
- 逆に読み込み側は BOM を除去してから処理 (Python は
encoding="utf-8-sig")
トラブル2: 改行コードで行が崩れる
RFC 4180 は CRLF を要求しますが、実際に流通する CSV には3種類の改行が混在します:
- CRLF (\r\n): Windows, RFC 4180 準拠
- LF (\n): Unix, macOS(現行)
- CR (\r): 古い Mac OS (OS X 以前、レガシー)
Excel for Mac 2011 以前は CR のみを期待していたため、今も「Mac でエクスポート → Windows で読めない」トラブルが稀に起きます。
追い打ちをかける問題: ダブルクォート内の改行も CSV の一部として許可されるため、「行数 = 改行数」とは限らない。雑にファイルを split("\n") で分割するパーサを書くと、改行を含むセルがある CSV を壊します。
# 1行目が "コメント" カラムに改行を含む場合
ID,氏名,コメント
1,田中,"次の行を
参照してください"
2,佐藤,通常のコメント
# 見かけ上 5 行だが、CSV としては 3 行 (ヘッダ + 2データ行)
トラブル3: 引用符・エスケープのパース失敗
フィールド内にカンマ、ダブルクォート、改行を含む場合のエスケープ規則:
# ソースデータ
氏名: "田中 太郎"
コメント: セミナーに参加、質問あり
メモ: 複数行
のテキスト
# CSV 表現 (RFC 4180 準拠)
"""田中 太郎""","セミナーに参加、質問あり","複数行
のテキスト"
ダブルクォートを含むとき、フィールド全体をダブルクォートで囲み、内部のダブルクォートを2つに倍化します。
よく見る実装の間違い:
- バックスラッシュ
\"でエスケープしてしまう (RFC 4180 違反、Excel で読めない) - シングルクォート
'で囲んでしまう (CSV ではダブルクォートのみ有効) - 先頭にダブルクォートがあればエスケープ必須なのに、カンマを含まないフィールドで囲まない (一部のパーサで失敗)
トラブル4: 先頭ゼロ・指数表記・日付の自動変換
これは Excel 側の「親切すぎる」機能が原因のトラブルです。
| CSV の元データ | Excel で開いた結果 | 原因 |
|---|---|---|
| 0123 | 123 | 数値として自動変換、先頭ゼロ消失 |
| 1.23E+10 | 1.23E+10 (科学記数法) | 大きな数値を指数表記で表示 |
| 3/4 | 2026/3/4 (日付) | 年/月/日として解釈 |
| 042-123-4567 | (4) 123-4567 等 乱れる | マイナス記号が演算記号と解釈 |
| 01F | 01F | (まれに) 16進数と解釈されて失敗 |
対処:
- CSV 側でタブ文字 (\t) を先頭に付ける → Excel が「文字列」と認識 (ただし一部の CSV リーダーで問題化)
- 出力時に ="0123" のように Excel 数式記法で包む (Excel 限定)
- 根本解決は CSV ではなく Excel 形式 (xlsx) で出力する
- 受信側に「テキストインポートウィザード」を使って明示的に型指定させる運用
Google Sheets / LibreOffice Calc との差分
| 項目 | Excel | Google Sheets | LibreOffice Calc |
|---|---|---|---|
| BOM 認識 | 必須 (日本語環境) | BOM無しでも UTF-8 と判定 | 読込ダイアログで選択 |
| 既定エンコーディング | Shift-JIS (BOM無時) | UTF-8 | 読込時に手動指定 |
| 引用符ルール | RFC 4180 準拠 | RFC 4180 準拠 | RFC 4180 準拠 |
| 日付自動変換 | しがち | しがち | しがち (設定で抑制可) |
| 改行コード | CRLF 出力、LF/CR も読める | LF 出力 | 環境依存 |
多くの実務トラブルは Excel の BOM 要求と既定 Shift-JIS が根本原因です。
代替フォーマットの検討
CSV の仕様曖昧さが問題ならば、以下の代替が有効です:
- TSV (Tab-Separated Values): カンマではなくタブ区切り。フィールド内のカンマを気にせず済む。RFC 4180 のような厳密仕様はないが事実上安定
- JSON / JSON Lines: 型情報を持つ (string/number/boolean/null/array/object)。大規模なデータ交換では推奨
- Excel .xlsx: OOXML 標準。型保持・数式・複数シート対応。SheetJS など JS ライブラリで読み書き可
- Parquet: 列指向バイナリ、大量データ高速処理。BigQuery / Athena 等で採用
- SQLite ファイル: 完全なリレーショナルデータ。SQL で問い合わせ可
「人が手でも編集する」前提でなければ、CSV を使う必然性は薄い、というのが業務データ交換の2020年代の潮流です。
実務チェックリスト
- CSV 出力するシステムはUTF-8 + BOMを既定に
- 改行はCRLFで統一
- 引用符エスケープはRFC 4180 準拠 ("") 、バックスラッシュ使用しない
- カラムにカンマ・ダブルクォート・改行が含まれる可能性があるなら常に引用符で囲む
- 先頭ゼロ・大きな数値・日付っぽい文字列はExcel で開いた時の挙動をテスト
- 可能なら xlsx / JSON / Parquet での代替を検討
- 読み込み側ではBOM除去とエンコーディング自動判定を忘れない
まとめ
- RFC 4180 は USASCII + CRLF + 最小エスケープ規則しか定めず、日本語 CSV の運用は別途配慮必要
- Excel は UTF-8 BOM 必須(日本語環境)、BOM無しだと Shift-JIS として読む
- 改行コードは CRLF が安全、LF/CR 混在に注意
- 引用符エスケープは
""(ダブルクォート倍化)、バックスラッシュ使用は RFC 違反 - 先頭ゼロ・日付っぽい文字列は Excel 自動変換に注意
- 業務データ交換は CSV より JSON / xlsx / Parquet の方が安全
参考文献・ソース
記事作成に関する注記
本記事は AI(大規模言語モデル)を編集補助として活用して作成しています。 公開前に編集者が内容を確認していますが、事実誤認・仕様の解釈ミス・最新情報との齟齬が含まれる可能性があります。 重要な判断を行う際は、本文中の一次ソースや公式ドキュメントを必ずご自身でご確認ください。 誤りにお気づきの場合は、お問い合わせフォームよりご連絡いただけると助かります。


