貼進來的已經不是表格裡那一格
做遷移的人都撞見過這一幕:Excel 裡一列訂單號,整塊複製、貼進轉換框,導出的 JSON 裡末尾幾位變了——110101199003072316 出來是 110101199003072320,長度仍是 18 位,只有末 2 位對不上;日期那一整列是帶引號的字串,行數一個不缺,就是當不了數字。第一反應是「工具算錯了」,但一位一位數過去會發現:失真分兩次,第一次在貼上那一刻就完成了。
能進文字方塊的只有字元。從 Excel 複製出來的是按儲存格格式渲染過的文字,工具看到的就是這串文字本身:2024/5/1、12,345.00、1.23457E+11、#N/A——都已經是 Excel 加工過的樣子,工具無從也沒有依據還原成日期或真實數字。
型別推斷只認 4 類,其餘一律落進字串
excel-to-json 裡唯一會改寫儲存格的步驟是型別推斷,辨識範圍只有整數、浮點、true/false、null 四類。勾選「自動識別資料型別(數字/布林值)」時實測如下:
| 貼進來的格子 | JSON 裡的樣子 | 發生了什麼 |
|---|---|---|
2024/5/1 | "2024/5/1" | 不在辨識範圍,落進字串 |
12,345.00 | "12,345.00" | 千分位當文字,只多 2 個引號 |
1.23457E+11 | "1.23457E+11" | 指數串原樣保留,兩種狀態一樣 |
#N/A | "#N/A" | 錯誤值也只是字串 |
007 | 7 | 被認成整數,前導零消失 |
110101199003072316 | 110101199003072320 | 被認成整數,末 2 位改寫 |
Excel 改寫過的四類文字(日期串、千分位、科學計數法、錯誤值)不在辨識範圍內,原樣退回成字串;看起來像整數的反倒被再加工一次——007→7、00→0、1.0→1、3.00→3、12345.67890→12345.6789、-0 寫成 0,全程沒有提示。裸值與帶引號值混在一份資料裡,下游怎麼讀標量,YAML 與 JSON 的標量型別改寫踩過同一組坑。
會不會失真,是位數和數值一起決定的
長數字容易被理解成「位數一多就出錯」,實測不是。15 位以內 3 個樣本都精確;16 位是否精確要看有沒有跨過 2^53(9007199254740992):同是 16 位,9007199254740991 原樣保留,9007199254740993 輸出成 9007199254740992。17 位起 3/3 失真,18 位普遍改掉末 2 位,19 位全 9 還進到 20 位。再往上就不是改幾位的問題:22 位起 JSON 常值換成指數形式,1000000000000000000000 輸出成 1e+21,長度從 22 字元縮到 5 字元。
也有被救回來的例子:末位帶一個字母(11010119900307231X),整串就不再被認成數字而保持字串——於是同一份 JSON 裡一行 number、一行 string。
想讓整列保持原文,只有一個開關
能整列保住貼上文字的只有一條:取消勾選「自動識別資料型別(數字/布林值)」。型別推斷在最前面短路,實測 48 組輸入在取消勾選後全部保持字串。邊界要劃清:保住的是貼進來那串字元,不是表格裡的原始精度——勾選或取消都不會讓 1.23457E+11 變回數字,也不會讓 2024/5/1 變回日期。
欄位是按 Tab 切死的,沒有分隔符可挑
切欄依賴寫死的 Tab,頁面上沒有分隔符控件,所以自動識別分隔符的說法不成立。CSV 直接貼進去,每列只算 1 欄——a,b,c 得到一個元素;標頭模式下整份資料塌成 1 個鍵。欄位內帶引號的 Tab 照樣被切開:zhang<TAB>"xin<TAB>guo" 切出 3 格,引號只是留在格子的字元。欄位內換行會把 1 列拆成 2 列,標頭模式下 2 列資料能變成 3 個物件,此後整表欄位都不再對齊。
重名標頭與第一欄做 key:行數會縮,統計條看不出來
標頭是物件輸出的鍵名,重名就在 JSON 裡塌縮:name + name + city 三欄只產出 2 個鍵,鍵的值來自第 2 欄(後寫覆蓋先寫);三欄同名只剩 1 個鍵;空欄名得到一個鍵 "",合法而無意義;資料欄比標頭多時,多出的欄靜默丟棄。
第一欄做 key 更陡:5 列只有 3 個不同的 key,輸出就 3 個鍵,2 列資料消失。統計條按物件鍵數顯示 資料列: 3,看不出丟了列。數字形的 key 還會被重排:貼上順序 42、7、3,輸出順序 3、7、42。
錯誤提示框基本看不到
這一頁的失敗幾乎都是靜默的結構改變。54 組實測輸入裡「解析錯誤」框顯示 0 次:空白類輸入被提前收進空態,非空輸入又至少留下 1 列,兩處拋錯分支走不到。單列輸入在標頭模式下只得到 [] 和 資料列: 0,頁面照常顯示,不作解釋。
規模不用擔心,體積要留意
沒有長度上限也沒有截斷錯誤:2000 列 5 欄、輸入 74669 字元一次跑完,美化輸出 156672 字元 / 14002 列,壓縮輸出 94671 字元。同一份資料 500 列時美化比壓縮多 15501 字元(約 1.7 倍),標頭模式又比陣列多 15000 字元——鍵名每列重寫一遍就是這筆開銷。輸出區那個 480px 只是顯示視窗,複製走的是全量文字;要比較兩份輸出的體積差,JSON 格式化裡的美化與壓縮口徑可以直接套用。
轉完之後建議核對這 4 處
- 最長的數字欄與貼上前逐位對:18 位以上先看末 2 位,22 位以上先看它有沒有變成
1e+21這種形狀。 - 鍵數與欄數對一遍:標頭有重名或空欄名時,鍵數一定小於欄數。
- 物件個數與貼上列數對一遍:第一欄做 key 與欄位內換行都會讓兩者不等。
- 需要原樣文字的欄,取消勾選再跑一次,與勾選結果並排留檔。
常見問題
Q:日期欄能不能轉成真正的時間?
不能。型別推斷裡沒有日期分支,2024/5/1 只保持帶引號的字串,45412 這種序列號也只被當普通整數,兩者都不被當日期。
Q:把型別辨識關掉,就能拿回原始精度嗎?
它拿回的是貼進來那串字元,不是儲存格裡的原始值。像 1.23457E+11 這種貼上時已成指數串的文字,關掉勾選仍是指數字串;18 位號碼則只有關掉勾選才不被再改寫。
Q:貼之前要不要先把 CSV 轉成 Tab 分隔?
要。分隔符只有 Tab,其他符號一律整列當成 1 格,所以先在試算表軟體裡按 Tab 複製再貼,別指望轉換框認得逗號。