JSON 轉 Excel 為什麼沒那麼簡單
JSON 和 Excel 對「形狀」的理解不一樣。JSON 是一棵樹:物件裡套物件,陣列裡裝著還帶陣列的物件。而工作表是一個矩形:列、欄,一個儲存格放一個值。
所以每一次 JSON 轉 Excel,本質上都是一組決策,而不是一個機械步驟:
- 文件裡哪一部分才是表格?API 回應通常把真正的資料列包在
data或results這類欄位裡。 - 巢狀物件怎麼辦?它必須變成額外的欄。
- 陣列怎麼辦?一個儲存格放不下三個值,總得捨棄點什麼。
null怎麼辦?超長整數怎麼辦?布林值呢?
把這些決策藏起來的工具能很快吐出一張表,也會安靜地把其中幾個決策做錯。這篇指南把每個決策對資料的實際影響攤開講清楚,讓你能核對結果,而不是只能相信結果。
三條實用路徑
| 方式 | 適合 | 代價 |
|---|---|---|
| 線上轉換器 | 臨時要把某個檔案或 API 回應弄進 Excel | 無需設定;但要確認工具是否上傳資料 |
| Excel Power Query | 以後還要從同一資料來源重新整理的匯入 | 需要學展開操作;只能活在某個活頁簿裡 |
| Python(pandas) | 定時任務與資料管線 | 需要執行環境;對單個檔案屬於殺雞用牛刀 |
下文先把線上這條路走細,再說明另外兩條什麼時候才是更好的答案。
第一步:找到 JSON 裡真正的表格
真實的 API 回應很少把資料列放在最上層,通常長這樣:
{
"data": [
{ "id": 1024, "name": "Alice Chen", "active": true },
{ "id": 1025, "name": "Bob Miller", "active": false }
],
"page": 1,
"total": 2
}
資料列在 data 裡。page 和 total 是關於這次回應的中繼資訊,不是表格的欄。
好的轉換器會自動辨識這一點:它會去找 data、items、records、rows、results、list 這些常見的包裹欄位名,取其中的陣列。如果你的 API 用了別的名字,或者陣列藏得更深,你可以自己填一個點號路徑來指定根節點,例如 response.payload.orders。
如果你讓工具對著整份文件而不是那個陣列轉換,結果就是一列,其中某個儲存格塞著整段 JSON。這是「轉換結果看起來壞掉了」最常見的原因。
第二步:看清巢狀怎麼變成欄
拿一筆同時包含巢狀物件、字串陣列和物件陣列的記錄:
{
"data": [
{
"id": 1024,
"name": "Alice Chen",
"active": true,
"score": null,
"address": { "city": "Berlin", "zip": "10115" },
"tags": ["pro", "beta"],
"orders": [
{ "sku": "A-1", "qty": 2 },
{ "sku": "B-7", "qty": 1 }
]
},
{
"id": 1025,
"name": "Bob Miller",
"active": false,
"score": 91.5,
"address": { "city": "Paris", "zip": "75001" },
"tags": [],
"orders": [{ "sku": "C-3", "qty": 5 }]
}
]
}
用預設設定轉換,得到的表格是這樣:
| Id | Name | Active | Score | City | Zip | Tags | Orders |
|---|---|---|---|---|---|---|---|
| 1024 | Alice Chen | TRUE | Berlin | 10115 | ["pro","beta"] |
[{"sku":"A-1","qty":2},{"sku":"B-7","qty":1}] |
|
| 1025 | Bob Miller | FALSE | 91.5 | Paris | 75001 | [] |
[{"sku":"C-3","qty":5}] |
這張表裡有三處值得細看。
巢狀物件變成了欄,標題取的是路徑最後一段。 來源路徑是 address.city,但欄標題是 City。這是刻意為之:把 address.city 當標題準確但難讀,而表格終究是給人看的。完整點號路徑會保留在對應面板裡,所以你隨時知道某一欄是從哪來的。
代價出現在兩個分支以同一個詞結尾的時候。如果記錄裡同時有 user.name 和 company.name,你會得到兩個都叫 Name 的欄。把檔案寄給別人之前,先在對應面板裡改掉其中一個。
null 變成了空儲存格。 不是文字 null,也不是數字 0。Alice 的 score 確實是缺失的,而空儲存格正是試算表表達「沒有」的方式。這一點很關鍵:=AVERAGE() 會略過空儲存格,但會把 0 老老實實算進平均值。
型別保住了。 91.5 在 .xlsx 裡是數值而不是字串 "91.5"。true 和 false 是布林值,所以 Excel 顯示成 TRUE/FALSE 並且可以直接篩選。那些把所有內容都寫成文字的轉換器,會逼你在匯入後把每一欄重新轉一遍型別。
第三步:決定陣列變成什麼
上面表格裡的 tags 和 orders 還是 JSON 文字——忠實,但在試算表裡沒什麼用。儲存格裡表示陣列有三種方式,選哪種取決於你打算拿這個檔案做什麼。
保留 JSON 文字(預設)。什麼都不丟。適合表格只是中間產物、後面還有程式會再解析這個儲存格的場景。
串接值。 ["pro","beta"] 變成 pro, beta,空陣列變成空儲存格。當陣列裡裝的是簡單標籤、並且這張表是給人看的,這是正確選擇。
計數。 ["pro","beta"] 變成 2,空陣列變成 0。當你在做報表、關心的是「有幾個」而不是「是哪些」時用它。因為結果是真正的數字,你可以立刻加總與排序。
| 來源資料 | 保留 JSON | 串接 | 計數 |
|---|---|---|---|
["pro","beta"] |
["pro","beta"] |
pro, beta |
2 |
[] |
[] |
(空) | 0 |
[{"sku":"A-1"},{"sku":"B-7"}] |
完整 JSON 文字 | {"sku":"A-1"}, {"sku":"B-7"} |
2 |
注意最後一列:把物件陣列串接起來,會得到沒人願意讀的東西。當陣列裡裝的是物件而不是標籤時,這三種方式都不合適——你需要的是第二張工作表。這部分見 JSON 陣列轉 Excel 工作表。
第四步:當心超長數字
這一條會無聲無息地毀掉資料,而且幾乎沒有轉換器會提。
JavaScript 的數字型別,以及 Excel 本身的顯示精度,都無法精確保存超過約 15 到 16 位有效數字的整數。像 9007199254740993123 這樣的訂單編號,只要中途被當成數字處理,就會變成 9007199254740993000。不報錯,檔案也能正常開啟,只是編號錯了。
解決辦法是把超長整數寫成文字而不是數字:
| 欄位 | JSON 裡的值 | Excel 裡的值 | 型別 |
|---|---|---|---|
orderId |
9007199254740993123 |
9007199254740993123 |
文字 |
small |
42 |
42 |
數值 |
只有 16 位及以上的整數會被這樣處理,一般數字仍然保持數值型別,不影響你繼續做計算。如果你曾經把一串長編號貼進試算表、發現末尾變成了一堆 0,就是這個原因。
第五步:下載前先看預覽
在任何轉換流程裡,最有價值的習慣就是下載之前先看一眼表格。具體看這幾項:
- 列數對不對?如果只有一列、外加一個巨大的儲存格,說明根節點選錯了(第一步)。
- 你關心的欄都在嗎?還是某個欄位只存在於部分記錄裡?
- 數值欄是靠右對齊的嗎?如果是靠左對齊,說明它是以文字形式進來的。
- 有沒有兩欄標題撞名(例如兩個
Name)? - 長編號是不是完整到最後一位?
能直接編輯預覽的轉換器——改標題、刪掉不需要的欄、修正某個儲存格——可以省掉一次匯出到 Excel 再回頭改的往返。
想跳過這些步驟: 我們的免費 JSON 轉 Excel 工具會在瀏覽器裡完成上面全部五步。它自動辨識陣列根節點、展平巢狀物件、讓你選擇陣列的匯出方式、提供可編輯預覽,並在本機產生 .xlsx——JSON 全程不會上傳到伺服器。
什麼時候該改用 Excel Power Query
當這次轉換不是一次性的時候,Power Query 才是對的工具。
適合用它的情況:
- 資料來自一個會變化的 URL,你希望按「重新整理」而不是重新轉換一遍。
- 這個活頁簿是別人會反覆開啟的週期性報表。
- 你需要把 JSON 和活頁簿裡已有的其他表格合併。
不適合的情況:你只想拿到一次檔案。Power Query 要求你透過介面逐層手動展開巢狀結構,一筆巢狀四層的記錄意味著大量點擊。
什麼時候該改用 Python
當轉換需要在你不參與的情況下反覆執行時,就該寫程式了。
import json
import pandas as pd
with open("response.json", encoding="utf-8") as f:
payload = json.load(f)
# json_normalize 會把巢狀物件展平成點號命名的欄
df = pd.json_normalize(payload["data"], sep=".")
df.to_excel("output.xlsx", index=False, sheet_name="Export")
pd.json_normalize 處理巢狀物件很稱職。物件陣列則需要一個明確的決定,和第三步是同一個問題:
# 一筆訂單一列,並把父層的識別欄位帶下來
orders = pd.json_normalize(
payload["data"],
record_path="orders",
meta=["id", "name"],
)
with pd.ExcelWriter("output.xlsx") as writer:
df.to_excel(writer, sheet_name="Customers", index=False)
orders.to_excel(writer, sheet_name="Orders", index=False)
Python 這條路有兩點要留意。to_excel 需要安裝 openpyxl。另外 pandas 會把 19 位的編號讀成浮點數並四捨五入,所以那些欄要傳 dtype=str,或者在寫出前先轉成字串。
JSON 轉 Excel 和 JSON 轉 CSV 怎麼選
兩者相鄰,但不相同。
| .xlsx | .csv | |
|---|---|---|
| 資料型別 | 數字、布林、日期保留型別 | 全部是文字 |
| 多個工作表 | 支援 | 不支援,一個檔案一張表 |
| 格式 | 凍結標題、篩選器、欄寬 | 無 |
| 編碼問題 | 沒有,編碼由格式本身定義 | 常見,尤其是中文內容在 Excel 裡 |
| 適合指令碼處理/版本比對 | 差 | 好 |
| 被其他工具匯入 | 支援廣泛 | 幾乎萬能 |
給人看的選 .xlsx,給程式讀的選 .csv。如果資料裡有中文而讀者用 Excel,.xlsx 能徹底繞開亂碼問題——CSV 需要哪些額外處理,見 JSON 轉 CSV 指南。
常見問題與成因
只有一列,一個超大儲存格。 根節點指向了整份文件而不是陣列。把根節點設為存放記錄的那個欄位。
部分記錄缺欄。 轉換器是根據實際見到的欄位來建欄的。如果 500 筆記錄裡只有 3 筆有 email 欄位,那一欄會存在但大部分是空的——這是正確行為,而且它在告訴你資料本身的情況。
兩欄標題相同。 兩個不同路徑以同一段結尾。在對應面板裡改掉一個。
長編號末尾變成 0。 整數超過 15 到 16 位後的精度遺失。改用會把它寫成文字的轉換器,或者在來源 JSON 裡就給它加引號。
數字加不了總。 它是以文字形式進來的。看對齊方式:文字預設靠左,數字靠右。
處理大檔案時瀏覽器當掉。 瀏覽器端轉換受記憶體限制,具體上限取決於裝置和瀏覽器,沒有一個通用的「安全檔案大小」可以引用。拆分輸入,或者改走 Python 那條路。
常見問題
怎麼把 JSON 檔案轉成 Excel?
有三條實用路徑。臨時轉一個檔案,用線上轉換器最快:貼上 JSON 或上傳檔案,核對預覽表格,下載 .xlsx。如果希望以後能從同一資料來源重新整理,用 Excel 內建的 Power Query。如果轉換需要定時執行或嵌進資料管線,用 Python 加 pandas。對單次的 API 回應或資料匯出來說,線上轉換器幾乎總是最短的路徑。
線上轉換 JSON 到 Excel 安全嗎?
完全取決於工具。很多轉換器會把檔案上傳到伺服器處理,如果 JSON 裡有客戶資料、金鑰或內部識別碼,這就是問題。純瀏覽器端的轉換器用 JavaScript 在本機完成解析和 .xlsx 產生,資料不離開你的電腦。貼上敏感內容前先看清工具的說明,正式資料優先選本機處理。別只看宣傳:真正本機處理的工具,在你斷網之後依然能正常運作。
不裝 Microsoft Excel 能產生 .xlsx 檔案嗎?
能。.xlsx 是一種公開的封裝格式標準,轉換器、指令碼和各類函式庫都可以在沒有 Excel 的情況下寫出合法的活頁簿。產生的檔案可以用 Excel、WPS Office、Google 試算表、LibreOffice Calc 和 Numbers 開啟。只有當你要用 Power Query 重新整理、巨集這類 Excel 專有功能時,才必須裝 Excel 本身。
該把 JSON 轉成 Excel 還是 CSV?
給人看的選 .xlsx,因為它能讓數字保持數值、布林保持布林,還支援多個工作表、凍結標題和篩選器。給程式讀的選 .csv,因為它是純文字,便於版本比對,幾乎任何工具都能匯入。如果資料裡有中文而讀者用 Excel,.xlsx 還能徹底繞開 CSV 常見的編碼亂碼問題。
為什麼轉換結果只有一列?
因為轉換器對著整份 JSON 文件轉換,而不是對著存放記錄的那個陣列,於是整份文件變成了一列,其中一個儲存格塞著全部內容。把根節點設成存放記錄的欄位即可,通常是 data、items、results 或 rows。這是轉換結果看起來壞掉最常見的原因。
JSON Lines(.jsonl)怎麼轉成 Excel?
JSON Lines 是一行一個 JSON 物件,並不是一份合法的完整 JSON 文件,所以大多數解析器會直接報錯。在開頭加一個左方括號、結尾加一個右方括號、記錄之間加逗號,把它包成陣列,就能像普通 JSON 一樣轉換。Python 裡可以直接用 pd.read_json(path, lines=True) 讀取。
小結
JSON 轉 Excel 是一連串關於「形狀」的決策:表格在哪、巢狀如何變成欄、陣列變成什麼、哪些值需要防著試算表軟體本身。一旦知道每個決策的效果,核對一次轉換結果大約只要三十秒。
單個檔案用線上轉換器並看預覽;需要重新整理的報表用 Power Query;需要定時執行的寫那十行 pandas。
立即把 JSON 轉成 Excel → —— 免費,全程在瀏覽器本機執行,不上傳、免註冊。