php 匯出 csv 給 excel 97-2003 使用的中文字編碼問題

匯出資料並不是太困難的事情,但是對於 excel 97-2003 這樣舊版本的 excel 來說,中文字的編碼是個麻煩

比較新的 excel 都已經開始支援中文字使用 utf-8 等常用的 unicode 編碼方式,但是再古早的年代,各種語言(中文、日文、許多的歐系語言)都有各自的編碼方式,然後同一個編碼可能在不同語言中都被用到,總之就是一團亂。

在 utf-8 一統江湖之前,ucs編碼也曾經獨領風騷一陣子(utf8 與 ucs差異),但是ucs-2 固定使用 2 bytes,也無法包山包海包所有語言,而 ucs-4 則是固定使用 4 bytes,在2000年前後那個年代實在是很浪費頻寬的一件事情。

所以當 utf-8 這個用 1~4 bytes,且沒有 byte order dependency (little-endian / big-endian)的編碼方式進入這個亂局後很快就一統江湖,以現在(2019)來說全球的網頁有超過九成都已經使用 utf-8。

而古早的 excel 97-2003 版本,對於中文文字是使用 ucs-2 LE BOM (little-endian, with byte order mark),所以如果是直接把csv資料寫入檔案,那麼用 excel 97-2003打開,中文文字會全部變成亂碼。

解決方式就是要用 mb_convert_encoding (為 mb_string library) 將資料轉成 ucs-2LE 編碼,然後加上檔頭的 BOM。

file_put_contents($filename, chr(0xFF) . chr(0xFE) . mb_convert_encoding($strdata, "UCS-2LE", "UTF-8"));

如果BOM改成 chr(0xFE) . chr(0xFF) 那就變成了 big-endian。