← 記事一覧

JSON を CSV に変換する方法 (および逆方向)

JavaScript、Python、オンラインで JSON ↔ CSV を変換。array-of-objects マッピング、クオートの規則、ネスト値、型の強制について解説。

JSON は API の言語、CSV は表計算ソフト、データベース、アナリストの言語です。両者の変換は日常的なタスクで、API レスポンスを Excel にエクスポートしたり、スプレッドシートを JSON に変換してインポートしたりします。本ガイドでは JSON から CSV、CSV から JSON への変換を JavaScript、Python、ブラウザで紹介し、ハマりやすいエッジケース(ネストデータ、クォート、型)も扱います。

中核となるマッピング:オブジェクトの配列 ⇄ 行

CSV ファイルはテーブルです:列名の見出し行が 1 行、その後はレコードごとに 1 行。これに自然に対応する JSON 形状は オブジェクトの配列 で、各オブジェクトが 1 行、各キーが 1 列になります。

// JSON
[
  { "id": 1, "name": "Ada Lovelace", "active": true },
  { "id": 2, "name": "Bob Khan", "active": false }
]
# CSV
id,name,active
1,Ada Lovelace,true
2,Bob Khan,false

ヘッダはすべてのオブジェクトキーの和集合(フィールドが異なるオブジェクトも揃います)、各行は各列に対応する値を引きます。

JavaScript で JSON を CSV に変換する方法

JavaScript には組み込みの JSON.toCSV はありませんが、変換自体は短く書けます。本当に必要な作業は エスケープ だけです:カンマ、ダブルクォート、改行を含む値はダブルクォートで囲み、内部のクォートは二重化しなければなりません。

function jsonToCsv(rows) {
  if (!rows.length) return '';
  const headers = [...new Set(rows.flatMap(Object.keys))];

  const escape = (v) => {
    if (v == null) return '';
    const s = typeof v === 'object' ? JSON.stringify(v) : String(v);
    return /[",\n\r]/.test(s) ? '"' + s.replace(/"/g, '""') + '"' : s;
  };

  const lines = [headers.join(',')];
  for (const row of rows) {
    lines.push(headers.map((h) => escape(row[h])).join(','));
  }
  return lines.join('\n');
}

typeof v === 'object' の分岐に注目してください:ネストされたオブジェクトや配列はフラットな CSV 表現を持たないため、慣例ではセル内に JSON テキストとしてシリアライズします。詳しくは後述します。

JavaScript で CSV を JSON に変換する方法

逆方向の落とし穴は CSV を正しくパースすること —— フィールドはクォートの内側にカンマや改行を含めるので、単純に split(',') はできません。小さなステートマシン(あるいは本番では papaparse のようなライブラリ)を使いましょう:

function csvToJson(text) {
  const rows = [];
  let row = [], field = '', inQuotes = false;
  for (let i = 0; i < text.length; i++) {
    const c = text[i];
    if (inQuotes) {
      if (c === '"' && text[i + 1] === '"') { field += '"'; i++; }
      else if (c === '"') inQuotes = false;
      else field += c;
    } else if (c === '"') inQuotes = true;
    else if (c === ',') { row.push(field); field = ''; }
    else if (c === '\n') { row.push(field); rows.push(row); row = []; field = ''; }
    else if (c !== '\r') field += c;
  }
  if (field || row.length) { row.push(field); rows.push(row); }

  const [headers, ...data] = rows;
  return data.map((cells) =>
    Object.fromEntries(headers.map((h, i) => [h, cells[i] ?? ''])));
}

Python で JSON と CSV を相互変換する方法

Python の標準ライブラリにはこれが組み込まれています —— 依存ライブラリは不要です。

import csv, json, io

# JSON -> CSV
rows = json.loads(json_text)
buf = io.StringIO()
writer = csv.DictWriter(buf, fieldnames=list(rows[0].keys()))
writer.writeheader()
writer.writerows(rows)
csv_text = buf.getvalue()

# CSV -> JSON
rows = list(csv.DictReader(io.StringIO(csv_text)))
json_text = json.dumps(rows, indent=2)

本当に効くエッジケース

ネストされたオブジェクトと配列

CSV はフラット、JSON はフラットではありません。値がオブジェクトや配列の場合の選択肢は 2 つ:単一セルに JSON としてシリアライズする(簡単で可逆)か、フラット化して address.cityaddress.zip のような複数列にする(読みやすいが情報損失があり、逆変換は難しい)。ラウンドトリップが必要なら、セル内 JSON が安全です。

CSV では型が失われる

CSV には型がありません —— すべてのフィールドはテキストです。CSV → JSON では、意図して数値に変換しない限り "1" は文字列です。007 のような値(文字列として保持すべき郵便番号/ID)や、数値にすると精度を失う巨大整数には注意してください。ラウンドトリップが無損になるときだけ強制変換しましょう。

クォートと区切り文字

カンマ、クォート、改行を含むフィールドは常にクォートしてください。地域設定によっては(欧州版 Excel ではよくある)区切り文字に ; を使います —— ある列だけ妙に見えるなら、まず区切り文字を確認しましょう。

キーが揃わない

JSON オブジェクトのキーが揃っていないなら、すべてのキーの和集合からヘッダを作り、欠落したセルは空のままにしてください —— 最初のオブジェクトがすべての列を定義していると仮定してはいけません。

Excel と UTF-8 BOM

Excel で開く CSV に非 ASCII 文字が含まれる場合は、UTF-8 BOM(バイト 0xEF 0xBB 0xBF)を先頭に付けてください。Excel は BOM なしの UTF-8 を旧来のエンコーディングとして読み、アクセント/アジア圏の文字を化けさせます。多くの CSV ライブラリにはオプションで BOM を出力する機能があります。

// JavaScript —— BOM を書き込んで Excel に UTF-8 を正しく読ませる
const out = '\uFEFF' + jsonToCsv(rows);

別の区切り文字(CSV vs TSV vs ;

「CSV」は常にカンマ区切りとは限りません。よくある変種:

  • TSV —— タブ区切り;値にカンマが多いときに安全。
  • 欧州版 Excel は小数点がカンマの地域では ; を区切り文字として出します。

開いたときに出力が変な 1 列に詰まって見えるなら、リーダーが想定する区切り文字とファイルが違うのです。1 つに統一しましょう(地域をまたぐ Excel には , + BOM の CSV、エンジニアリングパイプラインには TSV)。

実世界の CSV には PapaParse を

ユーザから来る CSV をブラウザ/Node でパースするなら、PapaParse を使ってください —— 区切り文字検出、クォート付きフィールド、複数行値、ヘッダ行、そして数値/真偽値の強制変換を行う dynamicTyping を備えます。上の手書きスニペットは信頼できるシンプルな入力には十分ですが、規模が出てきたら PapaParse の出番です。

JSON を CSV にオンラインで変換 —— セットアップ不要

一回限りの変換ならコードは完全に省略できます。JSON を fixjson の JSON to CSV コンバータ に貼って To CSV をクリック、または CSV を貼って To JSON をクリック。クォート処理、キーの和集合、型強制を自動で処理し、すべてブラウザで動作します —— アップロードしないので、顧客レコードや内部エクスポートを含むデータでも安心です。

よくある質問

JSON を CSV に変換するには?

JSON オブジェクトの配列を用意し、全キーの和集合からヘッダ行を作り、オブジェクトごとに 1 行書き出します —— カンマ、クォート、改行を含む値はクォートします。Python なら csv.DictWriter、JavaScript なら小さな関数で、または オンラインコンバータ に貼り付けてください。

CSV を JSON に変換するには?

CSV をパースして(クォート付きフィールドを尊重)、最初の行をヘッダとして扱い、続く各行をヘッダをキーとするオブジェクトに対応付けます。明示的に変換しない限り、すべての値は文字列で届くことを忘れずに。

ネストされた JSON オブジェクトは CSV ではどう表現されますか?

CSV はネストできないので、ネストされたオブジェクトや配列は通常、単一セル内に JSON テキストとして書くか、address.city のようなドット列にフラット化します。セル内 JSON は可逆な選択肢です。

JSON を CSV にオンラインで無料変換できますか?

はい —— fixjson のコンバータ は両方向を無料で、すべてブラウザで、アカウント不要・アップロード不要で変換します。

関連ツールとガイド