一、问题
将查询的数据以xls文件导出时(utf-8编码),数据正常;但以csv文件导出时,文件中的中文乱码,同样是utf-8编码,改成gbk编码导出时,中文显示正常。
本以为问题解决,后面导出含拉丁字符(如àæêàì)的数据时,以xls文件导出数据正常显示,以csv文件导出时,文件中的拉丁字符显示为“?”号。
相关视频教程推荐:java课程
二、解决方法
以csv方式导出的文件中默认不含bom信息,通过给将要输出的内容设置bom标识(以 ef bb bf 开头的字节流)即可解决该问题。
具体方法如下:
...outputstreamwriter outputstreamwriter = new outputstreamwriter(response.getoutputstream(), "utf-8"); // 要输出的内容 result = (string)contentmap.get(response_result); response.setheader("content-disposition", "attachment;filename=test.csv"); outputstreamwriter.write(new string(new byte[]{(byte) 0xef, (byte) 0xbb, (byte) 0xbf})); outputstreamwriter.write(result); outputstreamwriter.flush();
如果是以outputstream流实现的 ,参数可以按如下修改:
out = response.getoutputstream(); //加上utf-8文件的标识字符 out.write(new byte []{(byte) 0xef, (byte) 0xbb, (byte) 0xbf});
注:
bom: byte order mark,字节顺序标记(以下摘自百度百科)
在ucs 编码中有一个叫做 “zero width no-break space” ,中文译名作“零宽无间断间隔”的字符,它的编码是 feff。而 fffe 在 ucs 中是不存在的字符,所以不应该出现在实际传输中。
ucs 规范建议我们在传输字节流前,先传输字符 “zero width no-break space”,这样如果接收者收到 feff,就表明这个字节流是 big-endian 的;如果收到fffe,就表明这个字节流是 little- endian 的。
因此字符 “zero width no-break space(零宽无间断间隔)” 又被称作 bom。
utf-8 不需要 bom 来表明字节顺序,但可以用 bom 来表明编码方式。字符 “zero width no-break space” 的 utf-8 编码是 ef bb bf。所以如果接收者收到以 ef bb bf 开头的字节流,就知道这是 utf-8编码了。
windows 就是使用 bom 来标记文本文件的编码方式的。
相关文章教程推荐:java入门学习
以上就是java中将查询的数据以csv文件导出时出现乱码的详细内容。