DevToolBox

JSON→CSV変換したファイルがExcelで文字化けする原因と対処

JSONをCSVに変換してExcelでダブルクリックして開いたら、「日本語」が「譌・譛ャ隱・」のような 見慣れない漢字と半角カナの羅列になる――この定番トラブルの原因はファイルではなくExcelの文字コード判定です。 本記事では仕組みを理解した上で、BOM付きUTF-8での保存Excel側での取込指定の2系統の対処、 さらにネストしたJSONの平坦化とカンマを含む値の引用ルールまでまとめます。

When you double-click a CSV, Excel decodes BOM-less UTF-8 with the legacy ANSI code page (Shift_JIS on Japanese Windows), turning Japanese text into mojibake. This guide shows two fixes: prepend a UTF-8 BOM (U+FEFF) when writing the file, or import it via Data > From Text/CSV with code page 65001.

TL;DR

JSON to CSV Converter

JSONを貼り付けるだけで、ネストの平坦化・RFC 4180準拠の引用・BOM付きUTF-8ダウンロードまでブラウザ内で完結。Excelでそのまま開けるCSVを生成できます。

今すぐ試す →

1. 原因: ExcelはBOMなしUTF-8をShift_JISとして開く / Why Excel garbles UTF-8

CSVファイル自体には「この文字コードで読んでください」という情報がありません。Excelはダブルクリックで CSVを開くとき、ファイル先頭にBOM(Byte Order Mark)があればUTF-8として読みますが、BOMがなければOSのレガシーコードページ――日本語版Windowsでは Shift_JIS(正確にはcp932)――で読みます。UTF-8のバイト列をShift_JISとして解釈すると、 例えば「日本語」(UTF-8で E6 97 A5 E6 9C AC E8 AA 9E)は 「譌・譛ャ隱」+ 不正バイトという別の文字列に化けます。

化けた文字列に「」「」「」などの漢字や半角カナが 繰り返し現れるのが、UTF-8をShift_JISで誤読したときの典型的なパターンです。逆に言えば、ファイルのデータは1バイトも壊れていません。メモ帳やVS Codeで開くと正常に見えるのはこのためです (これらは内容から文字コードを推定します)。

CSV carries no encoding metadata. Without a BOM, Excel falls back to the system ANSI code page. The file itself is intact — editors that auto-detect encoding display it correctly.

2. 対処法1: BOM付きUTF-8で保存する / Fix 1: Write a UTF-8 BOM

配布するCSVを生成する側なら、これが最も確実です。ファイル先頭にU+FEFF(UTF-8ではEF BB BF の3バイト)を書き込むだけで、ExcelはUTF-8として認識します。

JavaScript(ブラウザでダウンロードさせる場合):

const csv = convertJsonToCsv(data); // 変換結果の文字列
const blob = new Blob(["\uFEFF" + csv], {
  type: "text/csv;charset=utf-8",
});
const url = URL.createObjectURL(blob);
const a = document.createElement("a");
a.href = url;
a.download = "data.csv";
a.click();
URL.revokeObjectURL(url);

Python(csvモジュール):

import csv, json

with open("data.json", encoding="utf-8") as f:
    rows = json.load(f)

# utf-8-sig が先頭にBOMを自動で書き込む
with open("data.csv", "w", encoding="utf-8-sig", newline="") as f:
    writer = csv.DictWriter(f, fieldnames=rows[0].keys())
    writer.writeheader()
    writer.writerows(rows)

Node.js:

import { writeFileSync } from "node:fs";
writeFileSync("data.csv", "\uFEFF" + csv, "utf8");

注意点として、BOMを考慮しないパーサーでこのCSVを読み返すと、1列目の列名の先頭にU+FEFFが混入します (pandasなら encoding="utf-8-sig" で読む、JavaScriptならs.replace(/^/, "") で除去)。BOMが原因でJSON.parse が落ちるケースは別ガイドで扱っています。

Prepend U+FEFF ("" in JS, encoding="utf-8-sig" in Python) when writing the file. Remember to strip the BOM when reading it back with BOM-unaware parsers.

3. 対処法2: Excel側で文字コードを指定して取り込む / Fix 2: Import via Power Query

受け取ったファイルを変更できない場合は、ダブルクリックではなく取込機能(Power Query)を使います。 Excel 2016以降 / Microsoft 365での手順は次のとおりです。

  1. 空のブックを開き、「データ」タブ →「テキストまたはCSVから」を選択
  2. 対象のCSVを選ぶと表示されるプレビューで、「元のファイル」ドロップダウンを 「65001: Unicode (UTF-8)」に変更(多くの場合は自動判定される)
  3. 区切り記号が「コンマ」になっていることを確認して「読み込み

Power Query経由なら、郵便番号「100-0001」や電話番号の先頭ゼロが数値変換で消えるという別の定番トラブルも、「データの変換」で該当列の型を「テキスト」にすることで回避できます。 旧来の「テキスト ファイル ウィザード」を使いたい場合は、ファイル → オプション → データ → 「テキストから(レガシ)」を有効化すると「データの取得」→「従来のウィザード」に現れます。

Use Data > From Text/CSV and set File Origin to 65001: Unicode (UTF-8). Power Query also lets you type columns as Text to keep leading zeros.

4. ネストの平坦化とカンマを含む値の引用 / Flattening & RFC 4180 quoting

文字コード以外で壊れたCSVになる二大原因が「ネストしたJSONの未処理」と「引用漏れ」です。 まず、CSVは平らな表なので、ネストしたオブジェクトはドット記法の列名に平坦化します。

[
  {
    "id": 1,
    "user": { "name": "田中太郎", "address": { "city": "東京" } },
    "tags": ["優良", "法人"]
  }
]

↓ 平坦化すると列は id, user.name, user.address.city, tags になります。配列は JSON文字列のままセルに入れるのが安全です(要素数が不定のため)。

id,user.name,user.address.city,tags
1,田中太郎,東京,"[""優良"",""法人""]"

次に引用ルール。RFC 4180では、フィールドにカンマ・改行・ダブルクォートの いずれかを含む場合はフィールド全体をダブルクォートで囲み、内部のダブルクォートは"" に二重化すると定めています。

値に含まれる文字 / Contains元の値 / Raw valueCSVでの表現 / Encoded field
カンマ / Comma東京都港区1-2-3, タワーA"東京都港区1-2-3, タワーA"
ダブルクォート / Quote通称"タワマン"物件"通称""タワマン""物件"
改行 / Newline1行目(改行)2行目全体を "..." で囲む(改行はそのまま保持)
上記なし / None田中太郎田中太郎(引用不要だが、付けても合法)

引用漏れがあると「列がずれる」「住所の途中で行が分かれる」といった、文字化けとは別の壊れ方をします。 自前実装で values.join(",") しているコードは要注意です。

Flatten nested objects into dot-notation columns, keep arrays as JSON strings, and quote any field containing commas, newlines or quotes, doubling inner quotes per RFC 4180.

5. English summary

Excel garbles Japanese text in a CSV converted from JSON because CSV files carry no encoding metadata: when you double-click the file, Excel only treats it as UTF-8 if it starts with a BOM (U+FEFF, bytes EF BB BF). Without one, it falls back to the legacy ANSI code page — Shift_JIS (cp932) on Japanese Windows — and the UTF-8 byte sequence decodes into nonsense kanji. The data itself is not corrupted, which is why text editors that auto-detect encoding show it fine. There are two reliable fixes. If you generate the file, prepend a BOM: in JavaScript build the Blob from "" + csv; in Python open the output withencoding="utf-8-sig". If you cannot modify the file, import it instead of double-clicking: Data > From Text/CSV, then set File Origin to 65001: Unicode (UTF-8). Power Query also preserves leading zeros in postal codes if you type those columns as Text. Finally, make the CSV itself robust: flatten nested JSON into dot-notation columns like user.name, keep arrays as JSON strings, and follow RFC 4180 quoting — wrap fields containing commas, newlines or double quotes in double quotes, and escape inner quotes by doubling them. One caveat: a BOM you add for Excel will leak into the first column name when read by BOM-unaware parsers, so strip^ (or use utf-8-sig) when reading the file back.

まとめ

JSON to CSV Converter

本記事の対処をワンクリックで。「BOM付きでダウンロード」をオンにすれば、Excelでダブルクリックしても文字化けしないCSVがその場で手に入ります。データは外部送信されません。

今すぐ試す →

関連ツール / Related tools

関連ガイド / Related guides