码迷,mamicode.com
首页 > 其他好文 > 详细

node转发请求 .csv格式文件下载 中文乱码问题

时间:2018-05-24 15:08:44      阅读:300      评论:0      收藏:0      [点我收藏+]

标签:nload   rds   puts   cvs   lis   top   查看   send   att   

用户无法直接访问后台接口 需要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

 

代码:

  const fs = require(‘fs‘);
  const http = require(‘http‘)
  const iconv = require(‘iconv-lite‘);
 * download(){       
          let queryString = this.req.query.filter;
        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格式文件下载 中文乱码问题

标签:nload   rds   puts   cvs   lis   top   查看   send   att   

原文地址:https://www.cnblogs.com/jlliu/p/9082587.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!