Excel打开csv格式⽂件中⽂乱码的解决
  【乱码解决】
  接到⼀个需求,需要将PC管理端页⾯的Excel⽂件下载改为CSV的格式。据说CSV也是⼀种⽐较通⽤的做法,因为Excel 各个版本对于单Sheet的⾏数都会有限制,⼤数据量的情况下直接⽤CSV会⽅便很多,另外如果使⽤Excel组装数据,那么接⼝实现的内存也会占⽤更多(更多的对象)。
  直接上代码:
package portCSVUtil;
import n.util.RFC5987StringUtils;
import com.opencsv.CSVWriter;
import org.springframework.web.servlet.view.AbstractView;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.OutputStreamWriter;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Map;
public class CsvView extends AbstractView {
public static final String TEMPLATE_KEY = "templateName";
public static final String OUTPUT_NAME_KEY = "output";transport造句简单翻译
public static final Integer LIMIT_RAW = 15000;
/**
* Subclasses must implement this method to actually render the view.
* <p>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<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception {
List<String[]> entryList = (List<String[]>) (TEMPLATE_KEY);
String fileName = (String) (OUTPUT_NAME_KEY);
String rfc5987FileName = RFC5987StringUtils.rfc5987_encode(fileName);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=\"" + rfc5987FileName + "\";filename*=utf-8''" + rfc5987FileName);
OutputStreamWriter outputStreamWriter = new OutputStream(),
StandardCharsets.UTF_8);
CSVWriter writer = new CSVWriter(outputStreamWriter);
for (int i = 0; i < entryList.size(); i++) {
String[] strings = (i);
writer.writeNext(strings);c语言标准库源码在哪看
}
writer.close();
}
}uuid mysql
  在Controller层:
append函数 python
@Controller
@RequestMapping(value = "/manage/order")
@Api(value = "API.VALUE", tags = "订单")
jsp中文全称public class ChargeOrderController {
@DubboReference
private ChargeOrderFacade chargeOrderFacade;
/**
* 带条件的csv下载
*
* @param model
* @return
*/
@ResponseBody
@RequestMapping(value = "/download", method = RequestMethod.GET)
public View downloadCsvView(HttpServletRequest request, Model model, ChargeOrderQueryVo queryVo) {
Search search = Search(request);
List<String[]> dataList = actCsvViewInfo(search, queryVo);
CsvView view = new CsvView();
String time = new SimpleDateFormat("yyyy-MM-dd").format(new Date());
model.addAttribute(CsvView.TEMPLATE_KEY, dataList);
model.addAttribute(CsvView.OUTPUT_NAME_KEY, String.format("订单-%s.csv", time));
return view;
}
}
  测试也能够正常下载CSV⽂件的,但是⽤Excel打开这个⽂件发现中⽂乱码,明明设置了UTF-8的怎么会乱码呢?再次尝试⽤记事本打开⽂件发现,中⽂是可以正常显⽰的。此时对⽂本另存为UTF8格式,再次⽤Excel打开,此时中⽂能够正常显⽰了。
  ⽹上搜索⼀番到了原因。csv⽂件前必须要加个BOM头,Excel才能正确打开⽂件。于是做如下修改:
...
List<String[]> entryList = (List<String[]>) (TEMPLATE_KEY);
String fileName = (String) (OUTPUT_NAME_KEY);
String rfc5987FileName = RFC5987StringUtils.rfc5987_encode(fileName);
response.setContentType("application/octet-stream");
response.setHeader("Content-Disposition", "attachment;filename=\"" + rfc5987FileName + "\";filename*=utf-8''" + rfc5987FileName);
OutputStreamWriter outputStreamWriter = new OutputStream(),
StandardCharsets.UTF_8);
byte[] bom = {(byte) 0xEF, (byte) 0xBB, (byte) 0xBF};
outputStreamWriter.write(new String(bom));
CSVWriter writer = new CSVWriter(outputStreamWriter);
for (int i = 0; i < entryList.size(); i++) {
String[] strings = (i);
writer.writeNext(strings);
}
writer.close();
...
  此时下载的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信息。

版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。