CSV 大概是資料格式裡最簡單的那一種。它是純文字,一行一列,值用逗號分開:
name,quantity,priceWidget,12,4.50
整個概念就是這樣,而這正是 CSV 活得比每一個想取代它的封閉格式都久的原因。每個程式都讀得了它、它很小、它在任何文字編輯器裡都打得開,而且你可以確切看到裡面有什麼。
它同時也是最可能在不告訴你的情況下毀損你資料的格式,而那些理由值得在你下次打開一個 CSV 之前就知道。
這一點一直在坑人,而且它是語言問題,不是軟體 bug。
在德文、法文、西班牙文、葡萄牙文和許多其他語系裡,逗號是小數點——4,50 是四點五。那逗號就不能同時拿來分隔欄位,所以那些語系的試算表軟體改用分號來寫、也預期讀到分號:
name;quantity;priceWidget;12;4,50
兩個檔案都叫 CSV。把分號版本拿去用逗號的程式開,每一列都會塌成單一欄。把逗號版本拿去用分號的程式開,同樣的事反過來發生一次。
檔案裡沒有任何標記說明它是哪一種。唯一可靠的解法是用匯入而不是點兩下,這樣你可以自己指定分隔符號。
如果一個值裡面本來就有逗號怎麼辦?它會被包在雙引號裡:
"Smith, John",12,4.50
而當一個值裡有引號,那個引號會寫成兩個來跳脫。一個欄位甚至可以含有換行,只要它有被引號包住——這就是為什麼你不能靠數 CSV 的行數來可靠地算出有幾列。
每一個正規的 CSV 工具都處理得了這些。手工拼出來的檔案——任何用逗號把字串接起來做出來的東西——通常處理不了,而破綻只會在某人的名字或地址剛好含有逗號的時候才出現。
這是這個格式最具破壞力的缺口,而且沒有好的答案。
一個 CSV 檔不含任何關於它字元編碼的宣告。不像 HTML 或 XML,它沒有地方可以說「這是 UTF-8」。打開它的程式只能猜。
Windows 上的 Excel 傳統上猜的是系統的本地代碼頁而不是 UTF-8。所以一個含有中文、日文或韓文——或者帶重音的歐洲字元——的 CSV,開起來是一堆讀不懂的符號,即使那個檔案完全正確。
兩個實務上的應對:
這是真正讓人付出代價的部分,因為它是無聲的,而且在你還沒做任何事之前就發生了。
CSV 沒有型別——每一個值都是文字。試算表會猜每一個值是什麼意思,而它的猜測在幾種反覆出現的情況下,自信地錯著:
01234 變成 1234。電話號碼、帳號、產品編號和身分證字號全都遭殃。1.23457E+15 的東西,而原本的數字是沒了,不是被藏起來。3-10 的值變成 10 月 3 日。這就是那個著名的問題,逼得遺傳學家把一些名稱老是被轉成日期的基因重新命名。關鍵細節:如果你接著存檔,損害就被寫回去了。原本的值無法從存檔後的副本救回來。
兩個習慣能防掉全部。任何你收到的 CSV,留一份沒碰過的副本。而當內容包含編號、識別碼或任何開頭有零的東西時,走匯入路線,並且在資料落地之前把那些欄位標記成文字。
而它做不到的:多個工作表、公式、格式、儲存格型別、合併儲存格、圖表,或任何巢狀結構。那些正是試算表格式和它並存的理由。