这篇文章适合有一定编码基础的人看,纯手动解决乱码问题请参见:

转码保存后,重新打开即可。

转码操作如下:

编辑器->另存为->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纯属是微软的习惯。

说了这么多,你是不是有点迷糊呢?其实,我也迷糊,所以我要继续去补知识了,拜~

解决CSV文件用Excel打开乱码问题的更多相关文章

  1. 如何解决PHP生成UTF-8编码的CSV文件用Excel打开乱码的问题

    为了识别 Unicode 文件,Microsoft 建议所有的 Unicode 文件应该以 ZERO WIDTH NOBREAK SPACE字符开头.这作为一个”特征符”或”字节顺序标记(byte-o ...

  2. csv 文件用Excel打开乱码

    最近在做一个上传的功能,记录下自己的感受. 刚开始我用的是excel上传:但是发现客户服务器有用64位的,使用的时候程序会报错: 未在本地计算机上注册“Microsoft.Jet.OLEDB.4.0” ...

  3. java导出csv文件使用Excel打开乱码问题

    写一个csv文件,发现使用 notpad++ 打开是没有问题的,但是使用 Excel 打开之后显示乱码 刚开始的代码是这样子的: ByteArrayOutputStream os = new Byte ...

  4. 解决PHP生成UTF-8编码的CSV文件用Excel打开乱码的问题

    在要输出的内容前先输出"\xEF\xBB\xBF", eg:要输出的内容保存在$content里$content = "\xEF\xBB\xBF".$conte ...

  5. PHP生成UTF-8编码的CSV文件用Excel打开乱码的解决办法

    什么是BOM? 在UCS 编码中有一个叫做”ZERO WIDTH NO-BREAK SPACE”的字符,它的编码是FEFF.而FFFE在UCS中是不存在的字符,所以不应该出现在实际传输中.UCS规范建 ...

  6. PHP生成UTF-8编码的CSV文件用Excel打开乱码的问题

    在你要输出的内容前先输出"\xEF\xBB\xBF",例如:你要输出的内容保存在$content里$content = "\xEF\xBB\xBF".$cont ...

  7. PHP 导出 CSV 文件用 Excel 打开出现中文乱码

    本篇文章由:http://xinpure.com/php-export-csv-file-opened-by-excel-appear-garbled/ 乱码情况 写了一段导出 CSV 文件的代码,可 ...

  8. 解决Arcgis10.2.2中dbf文件用EXCEL打开乱码问题

    1.开始 -- 运行,输入”Regedit“,打开 注册表 . 2.如是用的是 10.x 版本 ArcGIS Desktop,定位到 ‘计算机\HKEY_CURRENT_USER\Software\E ...

  9. CSV用excel打开乱码

    utf-8 csv 文件用 excel 打开乱码问题 其实这个问题很久之前遇到过, 应该是没解决, 当时的情况是openoffice打开正常而excel打开不正常, 后来也没解决了, 只能把编码转了. ...

随机推荐

  1. Kioskcached(1)之 Memcached & Redis & Kioskcached 性能测试对比

    前言:本文仅仅是作者自己在学习过程中的一次实验而已,或许因为各种因素会导致实验结果与你之前的认知不太一样,因此请你带着批判的眼光看待本文(本文不具有实际环境的参考性). 一:测试目的 在了解了一些No ...

  2. prometheus(5)之consul服务自动发现及pushgetway

    pushgetway(push上传metric数据) Pushgateway简介 Pushgateway是prometheus的一个组件,prometheus server默认是通过exporter主 ...

  3. js 鼠标和键盘事件

    js 鼠标和键盘事件 鼠标事件 聚焦事件 离焦事件 鼠标单击和双击 鼠标的其他事件 鼠标事件对象 键盘事件 鼠标事件 聚焦事件 <input type="text" id=& ...

  4. [python]Pytest+selenium+git+jenkins持续集成

    1安装pytest框架 &pip install pytest   #pytest &pip install pytest-html  #pytest html测试报告 2.工程介绍 ...

  5. cgdb | 一起边看源码边调试gdb吧

    简介 cgdb是一款轻量级的基于gdb的命令行可视化工具,关系大致如下: 尽管gdb本身可以通过layout src的命令显示源码布局,但是其功能还是过于简陋. 使用cgdb并不需要你重新去学习过多额 ...

  6. Python基础(迭代)

    # from collections import Iterable#collections模块的Iterable类型判断 # dict1 = {'a':111,'b':222,'c':333} # ...

  7. [nowcoder5669A]Ancient Distance

    对于一个$k$,可以二分枚举答案并判断,判断过程可以贪心找最深的点(线段树区间max)+倍增+线段树区间覆盖(清0)来实现,时间复杂度$o(klog_{2}n)$ 考虑反过来,暴力枚举答案$x$并求出 ...

  8. 2020第十三届全国大学生信息安全竞赛创新实践能力赛rceme writerup

    审计代码 传入参数a,进入parserIfLabel函数 发现参数a的模板,a的格式要匹配pattern,如{if:payload}{end if} 可知ifstr是a中匹配的第一组的值,即paylo ...

  9. 基于CarbonData的电信时空大数据探索

    摘要:作为IOT最底层的无线通信网络生成大量与位置相关的数据,用于无线通信网络规划和优化,帮助电信运营商建设更好体验的精品网络,构建万物互联的信息社会. 本文分享自华为云社区<基于CarbonD ...

  10. Golang知识点整理

    1. Golang 1.1 golang知识点大纲 1.2 指针 1.3 Golang使用validator进行数据校验及自定义翻译器 1.4 Golang GC(垃圾回收机制) 2.框架 2.1 G ...