一個可靠的 JSON 轉 CSV 替代方案,會在您的瀏覽器中執行完整的轉換,遵循常見的 RFC 4180 欄位與記錄規則,並且絕不會將您的資料上傳到遠端伺服器。這種組合正是您能否放心地把不受信任的記錄交給某個工具,還是會讓某個工具悄悄地把私有的 API 回應轉變成公開 POST 請求的實際差別。Lizely JSON 轉 CSV 轉換器正好符合這樣的描述:貼上非空、由物件組成的 JSON 陣列,它會依序掃描記錄以找出欄位,正確地為逗號、換行與巢狀 JSON 加上引號,並且在預覽中呈現與下載檔 converted.csv 完全相同的文字。一項預設的安全規則會在任何以公式觸發字元(=、+、-、@、Tab、Carriage Return,或 ECMAScript 空白字元觸發,例如前置 BOM 或不中斷空格)開頭的字串值或標頭前面加上單引號,再進行 CSV 跳脫,而試算表程式通常會將其視為要求以純文字處理。限制明確且絕不靜默處理,因此第 10,001 列會回傳錯誤,而不是產生一個被截斷的檔案。

json to csv alternative
json to csv alternative

為什麼開發者會尋找 Python 與 jq 之外的替代方案

在開發者論壇中最常被引用的捷徑,是基於 pandas 或 csv 模組的 Python 單行指令,或是管線化的 jq 運算式。兩者都能運作,但各自都帶有設定成本與若干正確性陷阱:

  • Python pandas: 需要執行環境已安裝 pandas,並會依據您的地區設定決定日期與數字格式,還會靜默地忽略或強制轉換它無法理解的內容。
  • 純 Python csv 模組: 需要自行撰寫引號與方言設定;只要在字串內部的逗號上出錯,輸出就會是格式錯誤的。
  • jq 搭配 @csv: 方便快速檢視,但會套用自身的跳脫規則,無法表達永遠啟用的公式保護,而且在處理大型陣列時難以編寫腳本。
  • 伺服器端的線上轉換器: 採取相反的取捨 — 零設定,但陣列會離開您的機器。對於開發者的測試資料與小型匯出而言,這樣的往返傳輸往往是多餘的風險。

基於瀏覽器的替代方案保留了開發者的心智模型 — 貼上記錄、取得 CSV、稽核結果 — 並以規則集中記載、可預測的轉換取代腳本編寫。

「RFC 4180 風格的 CSV」實際上需要什麼

CSV 看似簡單,但試算表、資料庫與分析工具對其接受哪種方言各有分歧。最常被引用的基準是 RFC 4180,而值得信賴的轉換器都會遵循它:

  • 欄位以逗號分隔。
  • 記錄以 CRLF 行尾字元分隔。
  • 包含逗號、雙引號、Carriage Return 或換行字元的欄位,必須以雙引號包起。
  • 引號欄位內部的雙引號以兩個雙引號表示。
  • 空白欄位保持空白;不附加尾端逗號。

美國國會圖書館在其 CSV 格式說明 中描述了相同的基準,將其定位為表格資料的通用交換格式。不遵循這些規則的轉換器所產生的檔案,在文字編輯器中看似正確,卻在試算表匯入的瞬間就壞掉。

此轉換器正好輸出這種格式:逗號分隔、CRLF 記錄結束字元、僅在必要時以雙引號包覆、內部引號以兩個雙引號表示。它不會加上 UTF-8 BOM、不會依據瀏覽器地區設定變更分隔符號、不會修剪空白字元,也不會推斷日期與數字格式。這種可預測性正是重點 — 預覽中的位元組,就是下載 Blob 中的位元組。

在本機將 JSON 陣列轉換為 CSV

開啟 Lizely JSON 轉 CSV 轉換器,並依照下列步驟在目前分頁中進行受控的轉換:

  1. 將非空、由物件組成的 JSON 陣列貼到輸入區,並確認其保持在計數器所顯示的可見限制之內。最外層為物件、基本型別、空陣列、null 列、陣列列或基本型別列,將會以明確訊息予以拒絕。
  2. 轉換記錄。轉換器會依序掃描已解析的物件,在每個欄位首次出現時將其加入標頭,因此後續的列可以加入額外的欄位而不會破壞結構。
  3. 在下載前檢視預覽。檢查欄位順序、巢狀物件與陣列的序列化方式、含有逗號或換行字元的欄位是否正確加上引號,以及結果摘要中所回報的有公式風險前置字元的數量。
  4. 下載 converted.csv,並在接收的應用程式中選擇 UTF-8 編碼、以逗號作為分隔符號,以及以雙引號作為文字辨識符號。

成功轉換後再編輯 JSON,會清除先前的 CSV 輸出、錯誤訊息與下載連結,因此分頁中不會留有過時的檔案。若轉換失敗,則不會顯示任何部分的 CSV — 只會顯示拒絕原因。新一次的轉換也會撤銷先前的 Blob 連結,而離開頁面則會釋放剩餘的連結。

將下載的 CSV 匯入 Excel、Google 試算表或 LibreOffice

由於檔案符合 RFC 4180 格式,匯入設定是可預期的。具體步驟會因程式而略有不同。

Excel(桌面版,現代版本)

  1. 雙擊 converted.csv,或使用 資料 > 從文字檔/CSV 匯入
  2. 出現提示時,將 檔案來源 設為 65001 (Unicode UTF-8),以便正確解碼不含 BOM 的檔案。
  3. 分隔符號 設為逗號,並將 文字辨識符號 設為雙引號。
  4. 確認預覽中顯示的欄位資料類型符合預期。以單引號開頭的儲存格應顯示為純文字,而不是將其視為公式求值。

Google 試算表

  1. 使用 檔案 > 匯入,並上傳 converted.csv
  2. 選擇 取代目前工作表,以逗號作為分隔符號,並將儲存格範圍設為 A1
  3. 確認預覽中,字串儲存格內部的引號化逗號會被視為字串的一部分,而不是欄位分隔。

LibreOffice Calc

  1. 開啟 converted.csv,或使用 插入 > 來自檔案的工作表
  2. 在文字匯入對話框中確認 UTF-8 編碼、逗號分隔符號,以及雙引號文字分隔符號。
  3. 決定是否要偵測特殊數字;若是為了原始資料交換,請保留精靈設定的標準欄位類型。

若在轉換過程中,以等號開頭的儲存格被加上了單引號前綴,則試算表會將單引號視為字串的一部分,而把該值當作文字處理。單引號在儲存格中並不可見,但會改變編輯時該值的求值方式。

公式保護:防禦 CSV 注入

試算表公式注入發生在某個 CSV 儲存格帶有以試算表解讀為公式觸發字元的字串時 — 通常是 =、+、- 或 @。當使用者開啟檔案時,試算表可能會將該儲存格執行程式碼、抓取外部資料,或回呼某個伺服器。OWASP 社群將 CSV 注入描述為資料匯出中一項被低估的風險。

此轉換器的回應是一項無法透過介面關閉的永久安全政策:

  • 任何以 =、+、-、@、Tab、Carriage Return 或 ECMAScript 空白字元(包括前置 BOM 或不中斷空格)開頭的欄位名稱與任何 JSON 字串值,都會被加上前置單引號。
  • 單引號是在 CSV 跳脫之前加入的,因此產生的欄位會在必要時以雙引號包覆,單引號會作為文字保留在引號化的值之內。
  • JSON 數值屬於具型別的資料,不會被加上前綴;像 -42 這樣的 JSON 數字在輸出中仍會是 -42,因為此風險適用於攻擊者可控的字串,而不是數值。
  • 轉換摘要會回報有多少儲存格被加上前綴,讓這項變更是可見的,而不是靜默進行的。

這項緩解措施刻意為了安全性而變更文字值,因此並非萬無一失的保證。後續的應用程式仍可能移除單引號、重新解讀文字,或套用不同的觸發規則。OWASP CSV Injection 頁面 記載了各種變體與下游風險,值得在可能執行程式碼、命令、連結或外部資料連線的軟體中開啟不受信任的匯出檔之前先行檢視。

避免靜默截斷的明確限制

會悄悄截斷過大輸入的轉換器會帶來不同類型的風險:您在預覽中稽核的資料與檔案中的資料並不相同。此 JSON 轉 CSV 轉換器會預先公開其界線,絕不會縮短輸出:

界線限制
JSON 輸入大小最多 1,000,000 個 JavaScript 字元
陣列列數最多 10,000 筆記錄
已探索結構最多 200 個唯一欄位
產生的 CSV最多 5,000,000 個字元

超出任何界線都會回傳錯誤,且不會產生縮短的 CSV。文字區會繼續顯示超過上限的輸入,計數器會標示溢量,而不是在輸入時裁切字元,因此使用者隨時都能精確看見所提交的內容。

瀏覽器型轉換器適用與不適用的情境

本機轉換器適用於您掌控記錄、希望快速取得回饋,且希望無論由哪個試算表開啟,檔案呈現結果都相同的場景:開發者的測試資料、REST 或 GraphQL 回應匯出、一次性交給非開發者的小型資料,以及絕不應離開分頁的敏感安全匯出。

它不適用於受規範資料的正式遷移、超過公開限制的非常大型資料集,或任何需要具型別欄位、明文化編碼宣告,或以特定方言進行下游處理的管線。CSV 並不承載資料類型、巢狀結構、編碼標頭,或通用的方言標記,因此超出扁平表格的內容,最適合仍以 JSON 保存。若您需要反向轉換,可使用 保留字串的本機 CSV 轉 JSON 替代方案,以相同方式運作,並在反方向套用相同的可預測規則。

此轉換只有在所公開的限制與規則之內才具有可預測性:空列會成為空白欄位、缺失的欄位會成為空白儲存格、巢狀陣列會以壓縮 JSON 形式保留在單一引號化的儲存格中,而與地區設定相關的格式永遠不會進入處理流程。請將預覽視為契約。若某個值的類型、巢狀結構或信任界線比扁平的一列更為重要,請將原始 JSON 與 CSV 一起保留,並在正式處理步驟中使用具結構感知能力的管線。

如需更深入的探討,請參閱 如何使用 Python 將 JSON 轉換為 Excel