node转发请求 .csv格式文件下载 中文乱码问题
Posted 刘家三胖
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了node转发请求 .csv格式文件下载 中文乱码问题相关的知识,希望对你有一定的参考价值。
用户无法直接访问后台接口 需要node端转发请求 并将数据以.csv文件格式生成以供客户端下载。 很不幸出现了中文乱码的问题
挖了各种坟帖,下了各种依赖包,csv、json2csv、bufferHelper、iconv-lite等等 多次尝试后 发现真正起作用的只有iconv-lite这个库
基本思路就是: 1. 修改header 信息,指定文件名和文件格
2. 设置返回值为二进制编码式
3. 将读取的数据段以二进制格式拼接成Buffer 此时buffer数据为GBK编码(后台返回数据的编码)的二进制数
4. 将Buffer字符串以GBK编码(注意这里需要与接口返回编码格式一致)解码 至此完成返回数据的中文乱码解决 此时为GBK格式的字符串
5. 将解码的字符串生成一个buffer
6. 将buffer以GBK格式编码 至此完成.csv文件需要的数据格式
如果接收的数据为JSON数据,就只要将其拼接成字符串,然后做1,5,6步就可以了
如果需要转成UTF-8格式 将第2步改成:
data = Buffer.concat([new Buffer(‘\xEF\xBB\xBF‘, ‘binary‘), new Buffer(_data)]); //excel需要BOM,每次写入数据前先加入一个utf8的BOM。utf-8对应的BOM是 EF BB BF
代码:
let fileUrl = URL + queryString; // download file let _this = this;
http.get(fileUrl, function (response) { //设置请求头 _this.res.setHeader(‘Content-disposition‘, ‘attachment; filename=orderData.csv‘); response.setEncoding(‘binary‘); //二进制binary
var data = ‘‘; response.on(‘data‘, function (_data) { data = Buffer.concat([new Buffer(‘binary‘), new Buffer(_data)]);
}).on(‘end‘, function () { //加载完
data = iconv.decode( data.toString(), ‘GBK‘); var buffer = new Buffer(data); var str=iconv.encode(buffer,‘GBK‘);
_this.res.send(str) }) })
Java端接口代码:
@TSPServiceInfo(name = "OPS.RPA.RecordController.recordListExport", description = "***csv") @RequestMapping(value = "/recordListExport", method = RequestMethod.GET) @IgnoreResponseLog @IgnoreRequestLog public String recordListExport(@RequestData RecordListRequestVO requestVO, HttpServletResponse response) throws Exception { if (requestVO.getCurrentUserId() == null && StringUtils.isEmpty(requestVO.getCurrentOperatorName())) { throw new InvalidParamException("参数错误"); } boolean forUser = requestVO.getCurrentUserId() != null; byte[] bytes = recordService.getRecordListBytes(requestVO, forUser); if (bytes.length == 0) { throw new EmptyResultException("没有查询到记录"); } try (final OutputStream os = response.getOutputStream()) { // 写出响应 HeaderUtil.responseCsvSetter("recordList", response); os.write(bytes); os.flush(); } catch (Exception e) { LOGGER.error("recordListCsv write response error", e); throw new EmptyResultException("结果返回异常"); } return ""; } @Override public byte[] getRecordListBytes(RecordListRequestVO request, boolean forUser) { RecordListParamEntity param = buildRecordListParam(request, RecordConst.RECORD_TYPE_HISTORY, forUser); /** * 运营端查看需要筛选用户 */ if (!forUser) { UserParamEntity userParam = buildUserParam(request); if (!BeanUtils.isAllFieldValueNull(userParam)) { List<Integer> userIds = userService.getUserIds(userParam); if (CollectionUtils.isEmpty(userIds)) { return new byte[0]; } if (userIds.size() < MAX_USER_COUNT) { param.setUserIds(userIds); } else { param.setUserType(request.getUserType()); param.setUserName(request.getUserName()); param.setDisplayId(request.getDisplayId()); } } } if (recordMapper.count(param) == 0) { return new byte[0]; } StringBuilder buf = new StringBuilder(); String cvsTitle = forUser ? RecordConst.USER_RECORD_LIST_CSV_TITLE : RecordConst.ADMIN_RECORD_LIST_CSV_TITLE; buf.append(cvsTitle).append(RecordConst.CSV_RN); int offset = 0; param.setOffset(offset); param.setLimit(SQL_QUERY_LIMIT); List<RecordDetailEntity> recordDetails = recordMapper.detailList(param); while (!CollectionUtils.isEmpty(recordDetails)) { buf.append(convertRecordsToCsvString(recordDetails, forUser)); offset += SQL_QUERY_LIMIT; param.setOffset(offset); recordDetails = recordMapper.detailList(param); } try { return buf.toString().getBytes("GBK"); } catch (UnsupportedEncodingException e) { LOGGER.error(e.getMessage(), e); return new byte[0]; } }
以上是关于node转发请求 .csv格式文件下载 中文乱码问题的主要内容,如果未能解决你的问题,请参考以下文章