zoukankan      html  css  js  c++  java
  • 解决Java以UTF-8导出的CSV文件用Excel打开乱码

    项目中导出或下载的CSV文件,默认打开方式一般都是Excel。若文件中有中文或者日文时,显示内容就会乱码,但是如果用文件编辑器记事本之类的打开显示内容是正常的。首先解释一下为什么会有这种现象,之后给出解决办法。

    乱码原因

    乱码的大多数原因是文件编码和工具打开文件使用的编码不统一导致。Excel打开的CSV文件默认是ANSI编码,如果CSV文件的编码方式为UTF-8、Unicode等编码可能就会出现文件乱码的情况。另外记事本支持UTF-8编码,所以用记事本打开显示正常。

    解决办法

    既然Excel不能识别文件是UTF-8编码,那就添加标识告诉Excel用UTF-8打开。需要添加的标识就是BOM标识,添加的原因之后会介绍。

    import java.io.BufferedWriter;
    import java.io.FileOutputStream;
    import java.io.OutputStreamWriter;
     
    public class Utf8BomTest {
        public static void main(String[] args) {
            FileOutputStream fos = null;
            OutputStreamWriter osw = null;
            BufferedWriter bw = null;
     
            try {
                fos = new FileOutputStream("d:\kou\test.csv");
     
                //追加BOM标识
                fos.write(0xef);
                fos.write(0xbb);
                fos.write(0xbf);
     
                osw = new OutputStreamWriter(fos, "UTF-8");
                bw = new BufferedWriter(osw);
     
                bw.write("1,测试1,测试2");
     
                //关闭流
                bw.flush();
                osw.flush();
                fos.flush();
                bw.close();
                osw.close();
                fos.close();
            }catch(Exception e) {
                e.printStackTrace();
            }
        }
    }
    
    

    追加BOM标识前

    Excel打开

    编辑器打开

    追加BOM标识后

    Excel打开

    编辑器打开

    扩展知识

    以上介绍了解决乱码的方法,为什么加了BOM标识后就不会乱码呢,感兴趣的朋友可以接着往下看。

    BOM中文名是字节顺序标记(英语:byte-order mark,BOM)是位于码点U+FEFF的Unicode字符的名称。常被用来当做标示文件是以UTF-8、UTF-16或UTF-32编码的标记。Windows就是使用BOM来标记文本文件的编码方式的。
    UTF-8不需要BOM来表明字节顺序,但可以用BOM来表明编码方式。当文本程序读取到以EF BB BF开头的字节流时,就知道这是UTF-8编码了。同理,若没有BOM的场合,可能无法正确识别编码,工具会使用默认的编码,编码不匹配则会导致乱码

    UTF-8文件中包含BOM的坏处
      1、对php的影响
      php在设计时就没有考虑BOM的问题,也就是说他不会忽略UTF-8编码的文件开头的那三个EF BB BF字符,直接当做文本进行解析,导致解析错误。
      2、在linux上执行SQL脚本报错

    参考文章

    1.Java UTF-8のテキストファイルをBOM付きで作成する
    https://www.javalife.jp/2018/02/26/post-441/
    2.字节顺序标记-维基百科
    https://zh.wikipedia.org/wiki/%E4%BD%8D%E5%85%83%E7%B5%84%E9%A0%86%E5%BA%8F%E8%A8%98%E8%99%9F
    3.UTF-8和BOM的一些说明
    https://www.cnblogs.com/codingmengmeng/p/11028744.html

  • 相关阅读:
    [SQL Server] sysobjects的介紹
    [R] [Johns Hopkins] R Programming -- week 3
    [R] 繪圖 Par 函数
    [R] [Johns Hopkins] R Programming -- week 4
    [Ms SQL] 基本創建、修改與刪除
    [R] Lexical & Dynamic Scoping / Execution & Calling environments / Closures
    [R] [Johns Hopkins] R Programming 作業 Week 2
    Python之路【第十七篇】:Django【进阶篇 】
    Django之Form组件
    Python之路【第十六篇】:Django【基础篇】
  • 原文地址:https://www.cnblogs.com/ghq120/p/13254343.html
Copyright © 2011-2022 走看看