上週三下午,營運同事丟過來一段介面回應,讓我「幫忙整理成表格」。那是訂單列表介面,外層是 {"code":0,"msg":"ok","data":{"total":28413,"list":[...]}},list 裡 500 條訂單,每條帶 order_no、pay_amount、create_time、buyer、items。我的第一反應是全選複製、貼進 Excel:結果所有內容擠在 A 欄,金額變成 1.00002E+15,日期那一欄只剩下幾個 #,一個多小時白做。事後看,問題不在 Excel 難用,而是我沒弄懂 JSON 和表格在結構上怎麼對應,也沒管住欄位的型別。
一、JSON 和表格其實是同一種東西的兩種畫法
對應關係很窄:物件陣列的每一項就是一行,物件裡的鍵就是欄名,值落在格子裡。反過來也成立——一張去掉表頭的表格就是一個物件陣列。
[
{"order_no":"20240915001","pay_amount":128.5,"city":"杭州"},
{"order_no":"20240915002","pay_amount":219,"city":"北京"}
]
order_no | pay_amount | city
20240915001 | 128.5 | 杭州
20240915002 | 219 | 北京
所以動手前的第一件事是確認「哪個陣列才是資料本身」。整包回應直接轉只會得到一行,欄名是 code、msg、data,看著沒錯但完全不能用;要單獨取 data.list。第二類麻煩是欄位不齊:那 500 條裡有 39 條沒帶 coupon_amount(沒用券),表頭必須取所有物件鍵的聯集、缺的留空;如果照第一條的鍵來定欄,就會無聲少掉兩欄,而且沒有任何提示。
二、真正花時間的是巢狀和一對多
buyer 是物件,展平成 buyer.nickname、buyer.phone 兩欄不丟資訊,讀著也更直白。items 是陣列,那一單最多有 12 個 SKU,硬塞進一格只會變成一段 JSON 文字,沒法做金額彙總。這種我會拆成兩張表:orders 一行一單,order_items 一行一件,兩邊用 order_no 關聯,業務側在 Excel 裡用樞紐分析表或 VLOOKUP 對上就行。
拆之前還要先把鍵名對齊。有的介面一處寫 create_time、另一處寫 createTime,表頭就憑空多出一欄同義欄位,報表裡沒人會去查它為什麼一半是空的。
三、我那天的處理順序
- 先驗證結構再動手。整段回應先丟進 JSON 格式化 過一遍,語法不合法時能拿到出錯的行列位置,比自己數括號快;常見情況是介面把一段 JSON 當字串塞進另一個 JSON,雙層轉義要先脫一層殼。
- 把
data.list單獨複製出來,貼進 JSON 轉 Excel 看渲染出的表格。預覽這步是關鍵:欄位實際抽出了哪些欄、要不要保留表頭列,都在預覽裡一眼能確認,不用等匯完再返工。 - 從預覽直接複製表格貼進 Excel,或者下載 CSV 再打開。給業務看的那份我另存成 xlsx,原始那份 CSV 不動,方便下次重算。
- 反向那次是業務把明細改完用 Excel 回傳,要變成 JSON 陣列給開發入庫。從 Excel 複製出來的是 Tab 分隔文字,Excel 轉 JSON 認這種貼上,數字和布林值會按型別輸出,省掉手工補引號。
表裡有手機號碼和收貨地址,所以我特意確認了這類轉換是在瀏覽器本機完成的、資料不送往伺服器端。即便如此,往外送之前還是應該把 phone 中間四位替換掉——這份 CSV 後來在群組裡轉了三手。
四、表格出來之後,Excel 裡要防這五個坑
| 現象 | 原因 | 怎麼辦 |
|---|---|---|
| 訂單號顯示成 1.00002E+15 | Excel 只保留 15 位有效數字,18 位單號的末幾位被抹成 0 | 該欄按文字匯入;已經變成科學記號的必須重新匯,被抹掉的尾數找不回來 |
| 中文欄變成「䏿–‡」這種怪字 | CSV 沒帶 BOM,Excel 拿本機 ANSI 去解 UTF-8 位元組 | 匯出帶 UTF-8 BOM 的那份,或在「資料→從文字」裡手工指定 65001 |
| 日期欄顯示 ###### | 欄寬不夠,或那個值本質上還是字串 | 雙擊欄邊界自動調整;字串日期用「資料剖析」按 YYYY-MM-DD 轉一次 |
| 備註裡一個逗號把一行劈成兩欄 | 欄位含分隔符卻沒有整體用雙引號包住 | 含逗號/換行的欄位必須加引號,欄位內部的雙引號寫成兩個 |
| 金額 1,280.50 變成文字或日期 | 千分位逗號讓 Excel 猜錯了型別 | CSV 裡只放裸數值,千分位交給 Excel 儲存格格式去做 |
這五條裡只有第一條是不可逆的。我那天貼壞的兩百多行單號就是重新匯了一遍才修回來。
五、常見疑問
Q:貼進去只有幾百行,介面明明說有兩萬多條?
多半是分頁。total 是 28413 而 list 長度是 500,說明手上只有第一頁。這種先翻完再轉,別把一頁當全量交出去。
Q:CSV 和 xlsx 該存哪個?
CSV 是純文字、單表、不帶樣式,任何語言都能讀,體積小,適合再進程式;xlsx 支援多工作表、公式和格式,適合交付給業務。我的習慣是 CSV 存檔、另存一份 xlsx 給看的人。
Q:匯出來的欄順序和我想的不一樣?
欄序取決於欄位在資料裡首次出現的先後,不是你期望的順序。想固定欄序,就在轉之前把欄位挑一遍、只留需要的鍵。
Q:資料量很大還能這麼處理嗎?
這類頁面是把文字讀進瀏覽器再渲染成表格,幾十萬行時光是渲染就夠卡。我的分界線是幾千行以內走這裡,幾萬行以上讓後端直接落檔案,或者分頁取完合併。
Q:轉出來的表怎麼核對沒丟資料?
看兩個數:來源陣列的長度對上表格列數,pay_amount 求和對上介面另給的彙總欄位。兩項都一致才算轉完,只挑幾行看是看不出漏欄的。
回頭看那個下午,真正讓我難看的不是不會轉表格,而是拿一份只有 500 條的資料做完了月報,第二天被財務指出總額差了三十萬。轉換本身是十分鐘的事,值錢的順序是:先確認哪個陣列是資料、再確認拿到的是不是全量、最後才定欄和型別——尤其是單號這種一旦被數值化就回不來的欄。