什麼是CSV檔案?
英文名:Comma Separator Value
(逗號分隔值),常用來資料轉換的中間檔案存在,比如:從Mysql
中匯出資料到CSV中。在web系統中經常遇到要匯出報表資料,也會用到csv格式,使用utf-8
編碼匯出CSV檔案,開啟后里邊的中文成了亂碼 (Windows下CSV檔案預設與Microsoft Excel
關聯),用文字編輯器開啟正常,不過排版很亂。原因:缺少BOM,又是微軟畫蛇添足。
什麼是BOM?
Byte Order Mark
(位元序標記),微軟定義的一種頭部結構。
為了識別 Unicode
檔案,Microsoft 建議所有的 Unicode 檔案應該以 ZERO WIDTH NOBREAK SPACE
字元開頭。這作為一個”特徵符”或”位元組順序標記(byte-order mark
,BOM)”來識別檔案中使用的編碼和位元組順序(big-endian
或little-endian
),具體的對應關係見下表。
Bytes Encoding Form 00 00 FE FF UTF-32, big-endian FF FE 00 00 UTF-32, little-endian FE FF UTF-16, big-endian FF FE UTF-16, little-endian EF BB BF UTF-8
類Unix系統中並沒有使用 BOM,因為它會破壞現有的 ASCII 檔案的語法約定。
我們在使用PHP匯出csv檔案時, 如果只使用file_put_contents
或者 fwrite
寫入了表格資料, 而我們生成csv的平臺不一定遵循微軟的bom協議,導致如果輸出非unicode編碼的csv檔案(例如utf-8),並且沒有生成bom資訊的話,Excel自動按照unicode編碼讀取,就會出現亂碼問題了。而沒有寫入BOM頭資訊,就會出現開啟中文亂碼的情況。
PHP中文亂碼解決
Excel在讀取csv的時候是透過讀取檔案頭上的bom來識別編碼的,如果檔案頭無bom資訊,則預設按照unicode
編碼讀取。
如果想使用utf-8格式,確保php原始碼是utf-8,我們可以在第一行寫入utf-8對應的BOM資訊
程式碼如下:
$bom = pack('CCC', 0xef, 0xbb, 0xbf); // 和上面的對應 file_put_contents('pythontab.csv',$bom, FILE_APPEND); file_put_contents('pythontab.csv',$someData, FILE_APPEND); //寫入你想要寫入表格的資料
前後都省略了部分程式碼, 只寫了最關鍵的部分, 其它部分大家自行補充即可。
這樣生成的csv
就不會出現中文亂碼問題啦。
注意:寫入的BOM
頭資訊要和檔案的編碼對應。