解決CSV文件用Excel打開亂碼問題


這篇文章適合有一定編碼基礎的人看,純手動解決亂碼問題請參見:

轉碼保存后,重新打開即可。
轉碼操作如下:
編輯器->另存為->ASCII碼格式文件/UTF-8含BOM格式->保存。

參考文章:https://blog.csdn.net/m0_37125796/article/details/73928157

我寫了一個CSV文件的數據列表,用Excel打開之后發現全部亂碼了,這讓我很尷尬。

於是找到了上面這篇文章,參照他的方式,進行了一些修改,終於解決了這個問題。

解決辦法:給CSV文件添加BOM頭

什么是BOM?

簡單來說,它是一個可以證明內容以什么編碼格式存在的中間人。

Excel是ASCII碼格式文件,而CSV文件是UTF-8格式。如果不進行兼容,這兩種不同格式肯定沒法正常展示的。

所以,我需要對UTF-8編碼的CSV文件寫入一個UTF-8的BOM頭,告訴Excel“我是UTF-8編碼的,你要按照我的編碼格式來解析。”這樣,Excel才能真正認清文件里的內容。

上面的參考文章給出的解決方案如下:

OutputStreamWriter osw = new OutputStreamWriter(resp.getOutputStream(), "UTF-8");  
// 要輸出的內容 
result = (String)contentMap.get(RESPONSE_RESULT);  
resp.setHeader("Content-Disposition", "attachment;filename=test.csv");  
osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB,(byte) 0xBF }));  
osw.write(result);  
osw.flush();  

我興高采烈地依葫蘆畫瓢,把我的代碼成他那樣,而且在我的mac電腦上已經運行成功了,Excel可以正常打開我的CSV文件。

於是,我興高采烈地交貨了,把我的成品發給了老大,讓他檢閱。

誰知,老大給我的答案是:“打開都是亂碼。”

“怎么可能,我在我電腦上能打開啊!”我下意識地反駁了一句,后來想想好傻啊,難不成是老大騙我嗎,還不趕緊去檢查代碼!

我帶着疑問,老大也過來幫我看哪里出了問題,先上一段我修改前的代碼:

            FileOutputStream fos = new FileOutputStream(file);
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));
            osw.write(s);
            osw.flush();

我按照參考的文章寫了這代碼,看起來好像沒什么問題。但是老大看出了貓膩,他把文件以16進制格式打開,發現我的BOM頭是EF BB 3F,而我寫入的BOM是EF BB BF。為何有這樣的差異,我的BF怎么變成3F了?

因為只有EF BB BF才能表示UTF-8,所以差一個字母都不行。

老大懷疑問題出在osw.write(new String(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF }));上,String默認是UTF-16的編碼,而我們寫入時應該不帶任何格式,才能讓解析器讀懂,如果被String這么一轉,轉成其他格式,這就不好說了。

不愧是老大,一語中的!

於是,我嘗試把String去掉,直接寫入byte數組的BOM。修改之后的代碼如下:

            FileOutputStream fos = new FileOutputStream(file);
            fos.write(new byte[] { (byte) 0xEF, (byte) 0xBB, (byte) 0xBF });
            OutputStreamWriter osw = new OutputStreamWriter(fos);
            osw.append(s);
            osw.flush();

原來的osw.write()也改成了osw.append()。(這個不改也無礙)

最終運行結果是可喜的,可以成功打開。

其實我們兩個電腦之間的差異,一個是windows,一個是mac。我懷疑是mac對BOM做了兼容,檢查沒有windows嚴格。后面我一查,其實UTF-8本身沒有BOM,給它加上BOM純屬是微軟的習慣。

說了這么多,你是不是有點迷糊呢?其實,我也迷糊,所以我要繼續去補知識了,拜~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM