JSON 轉 CSV

把 JSON 物件陣列轉換為符合 RFC 4180 的 CSV。自動將巢狀物件展平為點分列名,相容欄位缺失的記錄,支援逗號、分號、製表符、豎線分隔符以及 Excel BOM。

把記錄攤平成表格。 貼上一個物件陣列,即可得到帶表頭的 CSV。巢狀物件會變成點分列名,缺失欄位留空,包含分隔符的值會按 RFC 4180 加引號。

把樹變成表

形狀不匹配

JSON 是一棵樹,CSV 是一個矩形,因此任何轉換都必須決定如何處置樹上放不進矩形的部分。唯一能幹淨對映的形狀是「扁平物件組成的陣列」:每個物件一行,每個鍵一列。除此之外的一切都需要額外的規則。

巢狀物件是容易的一類。{"role": {"team": "core"}} 會變成名為 role.team 的列,既保留了取值路徑,也能被絕大多數電子表格匯入嚮導識別。巢狀陣列更棘手,因為展開它們會改變行數,並悄悄複製周圍的資料。本工具把它們作為 JSON 文本保留在單個單元格里——犧牲了可查詢性,但絕不會憑空造出源資料裡沒有的記錄。

欄位缺失與列順序

真實世界的 JSON 很少整齊劃一。這條記錄有 nickname,下一條沒有;某個欄位只在某次遷移之後才出現。如果轉換器只根據第一個物件確定列,其餘欄位就會被悄無聲息地丟掉。

這裡的列表是所有記錄中全部鍵的並集,按首次出現的順序排列。缺少某欄位的記錄會得到一個空單元格,而不是被跳過,因此行數始終與輸入的記錄數一致。選擇首次出現順序而非字母序,是為了保留作者原本的分組意圖——idname 會留在最前面,而不會被打散。

引號、分隔符與 Excel

RFC 4180 規定:欄位若包含分隔符、雙引號或換行,就必須加引號,而內嵌的雙引號通過寫兩遍來轉義。本工具對每個單元格(包括表頭)都應用這條規則,因此 Grace, Jr. 這樣的值或多行地址能夠完整地通過任何合規解析器往返。

分隔符的選擇比看上去重要。在以逗號作小數點的地區——歐洲大陸的大部分國家——Excel 期待的是分號,否則整行都會被塞進 A 列。BOM 選項會在檔案開頭加上 UTF-8 位元組序標記,正是它告訴 Windows 版 Excel 按 UTF-8 而不是舊式內碼表讀取;沒有它,非 ASCII 的名字會變成亂碼。這兩個選項都不在預設路徑上,恰恰因為它們會讓其他工具出問題——只在給 Excel 用時才打開。

開源說明:使用原生 JavaScript 實現,不依賴第三方庫。

常見問題

它期望什麼樣的輸入結構?
一個物件陣列,每個物件對應一行。單個物件也接受,會輸出一行;但由字串或數字組成的陣列無法變成表格。
巢狀物件是怎麼處理的?
會被展平成點分列名,例如 {"role": {"team": "core"}} 變成名為 role.team 的列。關閉展平則會把它們保留為 JSON 文本。
為什麼巢狀陣列保留為 JSON?
展開陣列會改變行數並複製周圍欄位。把它放在一個單元格里,可以保證輸出的行數始終等於輸入的記錄數。
各條記錄的鍵不一樣時會怎樣?
表頭取所有記錄全部鍵的並集,按首次出現的順序排列;缺少某欄位的記錄得到空單元格。不會跳過任何記錄。
什麼時候該開啟 BOM 選項?
只在給 Windows 版 Excel 用時開啟。位元組序標記會讓它按 UTF-8 讀取,否則非 ASCII 字元會顯示為亂碼。其他工具可能會把 BOM 顯示成多餘字元。
為什麼檔案在 Excel 裡全擠在一列?
Excel 遵循系統區域設定的列表分隔符。在用逗號作小數點的地區它期待分號,把分隔符改成分號後重新開啟即可。