586°

Nodejs以blob流方式编写JSON转EXCEL文件的导出服务

先说下业务需求,1.JSON转Excel表必须用xlsx格式,2.前端不能使用关于excel转换的插件,3.不能在后台生成相应的文件

前端纯js只能生成xls格式的Excel,因为公司前端环境比较稳定,在前端不能使用其他Excel插件的情况下,只能在后台用插件进行相关操作。但是因为不能生成文件,所以不能用传统的导出URL的方法。最后决定通过后台传blob的方法,再由前端转成文件。

 

导出

只有一个步骤,将要导出的数据发给后端即可。

    前端

      前端使用了fetch进行请求,如果用不了fetch,用ajax什么都可以,不过需要处理blob,百度上有很多。

let sendData = {
    FileName: "单元连接",  //表名
    data: dataMsg,      //json数据
    keys: ["Id","Desc","DataType","OperationType"]  //EXCEL里需要展示的json字段
  };
  fetch(`${window.serverURL}/api/entXlsxExport/download`, {
    method: 'POST',
    headers: {
      'Content-Type': 'application/json',
      Authorization:window.localStorage.token
    },
    body:JSON.stringify(sendData)
  }).then(response => response.blob())  //*注意:fetch的response自带blob()功能,需要将返回值先转一道
    .then(blob => {
    let url = window.URL.createObjectURL(blob);
    let a = document.createElement('a');
    a.href = url;
    a.download = `${sendData.FileName}.xlsx`;
    document.body.appendChild(a); 
    a.click();    
    a.remove();  

  }).catch(error => {
    console.log(error);
  })

      后端

        这里使用了“node-xlsx”的插件,他可以生成xlsx的buffer并返回;

       使用"express"搭的服务。passport是一个验证token的方法,不需要的可以删掉

const nodeXlsx = require('node-xlsx');

//将json转成Excel.elsx 格式并下载
  app.post('/api/entXlsxExport/download',passport.authenticate('jwt', {session: false}), function (req, res) {
    try {
     const {FileName, data, keys} = req.body;
     //  let data = [{name:"杜指导",job:"司机"},{name:"甘教练",job:"篮球"},{name:"施爹爹",job:"歌王"},{name:"朱行长",job:"翻墙"}];
     //  let FileName = 'shoes_club';  //表名,文件名       ************参数传入
     //  let keys = ["name","job"]; //这里设置表头      ********参数传入
      let sheet = [];
      if (!!data && data.length > 0) {
        if (!sheet[FileName]) {
          sheet[FileName] = {sheet: [], value: []};
        }
        sheet[FileName].sheet = keys;

        let values = []; //用来存储每一行json的数值,
        data.forEach( (item, index) => {
          values = [];
          keys.forEach( key => {
            values.push(item[key])
          });
          sheet[FileName].value[index] = values;
        });
      }
      sheet[FileName].value.unshift(sheet[FileName].sheet);
      let fileSheet = sheet[FileName].value;
      let obj = [{name: FileName, data: fileSheet}];
      let file = nodeXlsx.build(obj);  //这一步将符合要求的数据拼成buffer
      res.setHeader('Content-Type', 'application/vnd.openxmlformats'); //setHeader一定要写在生成buffer的下面
      res.setHeader("Content-Disposition", "attachment; filename=" + ` ${encodeURIComponent(FileName)}_${Date.now()}.xlsx`);  //不能使用中文
      res.writeHead(200);

      res.end(file);
    }
    catch (err) {
      return res.status(500).json({success: false, data: err.message});
    }
  });

 

本文由【chuanshuog】发布于开源中国,原文链接:https://my.oschina.net/u/3758485/blog/3001753

全部评论: 0

    我有话说: