JSON 工具箱

JSON 轉 Excel:四種辦法與它們各自的失真點

結論:巢狀結構、欄位不一致、陣列套陣列,是 JSON 轉表格最容易翻車的三處。四種辦法按「幾分鐘出結果」排序,每個都標清楚會丟什麼。

入門約 11 分鐘發佈於 2026-10-30更新於 2026-10-30
JSON 轉 Excel 實踐封面

結論:扁平物件陣列與物件包陣列直接用線上工具最快,需要每週重新整理就上 Power Query,欄位多要清洗用 Python + pandas,要接進流水線再寫 Node 指令碼;動手前一旦發現巢狀或鍵不一致,先定清楚「一行代表什麼」。

轉換本身不難,難的是「轉完之後發現數字變成文字、多層巢狀只剩一層」。選方法之前先看清資料結構,能省掉一次返工。

一、先判斷你的 JSON 屬於哪一類

開啟檔案看最外層:

結構 樣子 轉換難度
扁平物件陣列 [{"a":1,"b":2},{...}] 最容易,一行一條記錄
物件包陣列 {"data":[{...}],"total":100} 容易,取 data 那一層
巢狀物件 {"user":{"name":"x"}} 中等,要決定展開還是拼字串
陣列套陣列 {"tags":["a","b"]} 麻煩,一行裝不下,得拆表
鍵不一致 每條記錄的欄位不同 麻煩,列會大面積空值

前兩類直接轉,成功率接近 100%;後三類先想清楚「一行代表什麼」,否則轉出來的表沒法用。

二、方法一:線上工具(1 分鐘)

開啟 JSON 轉表格,貼上資料 → 選分隔符與表頭 → 匯出 CSV → Excel 開啟。適合幾十行到幾千行、結構規整的資料。

三個必須注意的點:

  • 匯出的是 CSV,不是 xlsx。Excel 開啟 CSV 時預設按系統編碼猜,中文可能亂碼。用「資料 → 從文字/CSV」並顯式選 UTF-8 更穩。
  • 以 0 開頭的編號會掉零。"007" 在 CSV 裡是文字,Excel 會自動轉成數字 7。匯入時把該列設為文字,或者在 JSON 裡給它加個字首。
  • 長數字會變科學計數法。身份證號、訂單號超過 15 位就會精度丟失,這類欄位在 JSON 裡本來就該是字串,匯入後也要保持文字格式。

三、方法二:Excel 自帶 Power Query(可複用)

資料每週都要更新時,用 Excel 內建的 Power Query,配置一次以後點「重新整理」就行:

  1. 「資料」→「獲取資料」→「自檔案」→「自 JSON」;
  2. 選中檔案後進入 Power Query 編輯器,看到的是 List / Record 結構;
  3. 點列標題右側的展開圖示,逐層展開巢狀欄位;
  4. 確認列名與型別後,「關閉並上載」。

好處是巢狀能一層層展開成多列,而且型別可以手動指定;代價是第一次配置需要理解 List 和 Record 的區別——List 是陣列,Record 是物件,展開方向不一樣。

四、方法三:Python + pandas(欄位多、要清洗時)

import pandas as pd

# 物件包陣列:先取到列表那一層
rows = pd.read_json('data.json')['data']

# 巢狀欄位展開成多列
frame = pd.json_normalize(rows, sep='_')

frame.to_excel('out.xlsx', index=False)

json_normalize 的關鍵引數是 sep,它決定巢狀欄位展開後的列名風格,user_name 比 user.name 在 Excel 裡更好用。陣列套陣列(比如 tags)需要額外一步 explode:

frame = frame.explode('tags')

這一步會把一行拆成多行,是唯一能保留「一對多」關係的做法,代價是其餘欄位重複。

五、方法四:Node 指令碼(要接進流水線時)

import { readFileSync, writeFileSync } from 'node:fs';

const rows = JSON.parse(readFileSync('data.json', 'utf8'));
const headers = [...new Set(rows.flatMap((row) => Object.keys(row)))];
const escapeCell = (value) => `"${String(value ?? '').replaceAll('"', '""')}"`;
const lines = [
  headers.join(','),
  ...rows.map((row) => headers.map((key) => escapeCell(row[key])).join(',')),
];

writeFileSync('out.csv', '\uFEFF' + lines.join('\n'), 'utf8');

兩個細節別省:開頭寫 \uFEFF(BOM)讓 Excel 認 UTF-8;單元格里的雙引號要成對轉義成 "",否則列會錯位。

六、轉換一定會丟的三樣東西

丟失項 表現 補救
型別資訊 數字、布林都變成文字或 TRUE/FALSE 匯入後手動設列型別,或用 Power Query 指定
巢狀層級 深層欄位被壓成 [object Object] 用 json_normalize 或逐層展開,別直接 String(obj)
一對多關係 陣列被塞進一個單元格 explode 拆行,或單獨建一張關聯表

另外,null 與「欄位不存在」在表裡看起來一樣(都是空單元格),但業務含義不同。需要區分時,在 JSON 裡把 null 顯式轉成字串 "null",或者加一列 _has_field 標記。

七、回頭驗證:別隻看第一行

轉完至少抽查三處:

  1. 記錄條數:CSV 行數應等於陣列長度 + 1(表頭),少一條通常是末尾換行被吞;
  2. 空值率最高的列:空得多說明鍵名不一致,回去看原始 JSON 是不是有兩種寫法(userId 與 user_id);
  3. 最長的那一行:巢狀陣列通常在這裡,確認沒有被截斷。

需要反向操作(Excel/CSV 轉回 JSON)時,用 CSV 轉 JSON,注意表頭會被當作鍵名,改表頭等於改欄位名。

常見問題

線上工具、Power Query 與 pandas 該如何取捨?

線上工具適合幾十行到幾千行、結構規整、只轉一次的資料,貼上後選分隔符與表頭即可匯出 CSV。Power Query 配置一次後點重新整理就行,適合每週都要更新的資料。欄位多、需要清洗時用 Python + pandas 的 json_normalize,要接進流水線再寫 Node 指令碼。

為什麼轉成 CSV 後中文會亂碼?

線上工具匯出的是 CSV 而不是 xlsx,Excel 開啟 CSV 時會按系統編碼猜,UTF-8 無 BOM 的中文就會亂碼。匯出時在開頭寫 \uFEFF(BOM),或在 Excel 裡用「資料 → 從文字/CSV」並顯式選擇 UTF-8。

能否保留原始 JSON 的巢狀層級?

可以,但要逐層展開而不是轉成字串:Power Query 能點列標題的展開圖示一層層展開成多列,pandas 用 json_normalize 配合 sep 把巢狀欄位拆成列。深層欄位直接 String(obj) 只會得到 [object Object],陣列套陣列還要額外做一步 explode。