2023年11月28日发(作者:)
Excel打开csv格式⽂件中⽂乱码的解决
【乱码解决】
接到⼀个需求,需要将PC管理端页⾯的Excel⽂件下载改为CSV的格式。据说CSV也是⼀种⽐较通⽤的做法,因为Excel
各个版本对于单Sheet的⾏数都会有限制,⼤数据量的情况下直接⽤CSV会⽅便很多,另外如果使⽤Excel组装数据,那么接
⼝实现的内存也会占⽤更多(更多的对象)。
直接上代码:
package CSVUtil;
import 5987StringUtils;
import ter;
import ctView;
import rvletRequest;
import rvletResponse;
import StreamWriter;
import rdCharsets;
import ;
import ;
public class CsvView extends AbstractView {
public static final String TEMPLATE_KEY = "templateName";
public static final String OUTPUT_NAME_KEY = "output";
public static final Integer LIMIT_RAW = 15000;
/**
* Subclasses must implement this method to actually render the view.
* The first step will be preparing the request: In the JSP case,
* this would mean setting model objects as request attributes.
* The second step will be the actual rendering of the view,
* for example including the JSP via a RequestDispatcher.
*
* @param model combined output Map (never {@code null}),
* with dynamic values taking precedence over static attributes
* @param request current HTTP request
* @param response current HTTP response
* @throws Exception if rendering failed
*/
@Override
protected void renderMergedOutputModel(Map
List
String fileName = (String) (OUTPUT_NAME_KEY);
String rfc5987FileName = 5987_encode(fileName);
tentType("application/octet-stream");
der("Content-Disposition", "attachment;filename="" + rfc5987FileName + "";filename*=utf-8''" + rfc5987FileName);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(putStream(),
_8);
CSVWriter writer = new CSVWriter(outputStreamWriter);
for (int i = 0; i < (); i++) {
String[] strings = (i);
ext(strings);
}
();
}
}
在Controller层:
@Controller
@RequestMapping(value = "/manage/order")
@Api(value = "", tags = "订单")
public class ChargeOrderController {
@DubboReference
CsvView view = new CsvView();
String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
ribute(TE_KEY, dataList);
ribute(_NAME_KEY, ("订单-%", time));
return view;
}
}
测试也能够正常下载CSV⽂件的,但是⽤Excel打开这个⽂件发现中⽂乱码,明明设置了UTF-8的怎么会乱码呢?再次
尝试⽤记事本打开⽂件发现,中⽂是可以正常显⽰的。此时对⽂本另存为UTF8格式,再次⽤Excel打开,此时中⽂能够正常
显⽰了。
⽹上搜索⼀番找到了原因。csv⽂件前必须要加个BOM头,Excel才能正确打开⽂件。于是做如下修改:
...
List
String fileName = (String) (OUTPUT_NAME_KEY);
String rfc5987FileName = 5987_encode(fileName);
tentType("application/octet-stream");
der("Content-Disposition", "attachment;filename="" + rfc5987FileName + "";filename*=utf-8''" + rfc5987FileName);
OutputStreamWriter outputStreamWriter = new OutputStreamWriter(putStream(),
_8);
byte[] bom = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
(new String(bom));
CSVWriter writer = new CSVWriter(outputStreamWriter);
for (int i = 0; i < (); i++) {
String[] strings = (i);
ext(strings);
}
();
...
此时下载的csv⽂件使⽤excel能够正常打开,且中⽂显⽰正常。
————————————————————————————————————————————————
【BOM是什么】
BOM的全称是Byte Order Mark,字节顺序标记。它是⼀种特殊的Unicode字符,作为⼀个魔数⼀样的存在,可以告诉正
在读取这个⽂本流的程序三件事情:
1.16位或者32位编码的情况下,⽂本流的字节顺序;
2.⼀个⽐较⾼级别的确认信息,表明这个⽂本流的格式是Unicode;
3.使⽤了Unicode字符编码。
但是这个BOM信息,⽤不⽤都是可选的,有些软件⽀持,有些软件不⽀持。在Windows环境下,很多软件都是⽀持,甚
⾄要求这个BOM信息的;但是UNIX环境下,如果携带了BOM信息,很多时候⼜会出问题。所以,这⾥要注意的是,到底使
⽤这个流的软件是否⽀持BOM,到了Windows环境下,如果出现了乱码,要能想到这个问题点;⽽在Linux环境下,或者是
跨平台的软件,如果出现了问题,⼜要排除这个点。
有些软件对于BOM的设置是可选的,⽐如Intellij Idea中对于配置⽂件的设置,就可以选择;Notepad++中也是可以选
的。是否选择,完全看我们的需求,但是使⽤不当也会带来上述问题。
另外,要注意的是,Windows处理⽂本时,会⾃动加上这个BOM信息。⽐如,新建⼀个⽂本,另存为的时候,选择
UTF-8格式,保存⽂件,此时可以看到⽂本的⼤⼩变成了3字节,这个3字节就是被加上了BOM信息。


发布评论