参考文档:

http://www.webkaka.com/tutorial/asp.net/2021/082435/

https://blog.csdn.net/pbm863521/article/details/103164385

一、背景与问题

  系统需要生成文件,内容可通过excel展示。由于是单页且会多次追加,故从性能考虑文件从xlsx改为csv。

  修改后,记事本和wps都可以正常打开,MicroSoft office excel打开中文乱码

二、解决

  查找资料后得知,

  BOM(byte-order mark),即字节顺序标记,它是插入到以UTF-8、UTF16或UTF-32编码Unicode文件开头的特殊标记,用来识别Unicode文件的编码类型。对于UTF-8来说,BOM并不是必须的,因为BOM是用来标记多字节编码文件的编码类型和字节顺序(big-endian或little- endian)。而UTF-8中,每个字符的编码有多少位是通过第一个字节来表述的,而且没有big-endian和little-endian的区分。
UTF-8 不需要 BOM,尽管 Unicode 标准允许在 UTF-8 中使用 BOM。所以不含 BOM 的 UTF-8 才是标准形式,在 UTF-8 文件中放置 BOM 主要是微软的习惯(顺便提一下:把带有 BOM 的小端序 UTF-16 称作「Unicode」而又不详细说明,这也是微软的习惯)。
BOM是为 UTF-16 和 UTF-32 准备的,用于标记字节序(byte order)。微软在 UTF-8 中使用 BOM 是因为这样可以把 UTF-8 和 ASCII 等编码明确区分开,否则用Excel打开CSV文件有可能是乱码的
  UTF-8 的网页代码不应使用 BOM,否则常常会出错。当从http 的response输出CSV文件的时候,设置为utf8的时候默认是不带
bom的,但是windows的Excel是使用bom来确认utf8编码的,所有需要把bom写到文件的开头。

 即 \uFEFF

方法1:用记事本打开csv文件,另存为ASCII编码格式,excel可以正常打开。

  但是作为一个系统,不能要求客户做方法1的操作,还是需要从代码根本上解决

方法2:插入UTF-8 BOM

C#如下所示

UTF8Encoding utf8 = new UTF8Encoding(true);
using (StreamWriter sw = new StreamWriter(path, true, utf8))
{
}

 JAVA如下

 File file = new File(filePath);
        if (!file.exists()) {
            //MS的excel要求要有BOM头否则打开中文乱码
            builder.append("\uFEFF");
}