文件Buffer转excel表格 vue+axios+node

826 阅读2分钟

后端数据转为Blob 前端将Blob转为excel文件

1. 数据获取

后端获取对应血压数据 后端将列表数据转变为数据流

  • 规定表头设置响应体
//数据表格
    let data = [];
    //非管理员用户只导出自己的血压
    if(userAdmin === false){
        data[0] = ['日期','时间段','高压','低压','心跳','备注'];
    }else{//管理员表头不同
        data[0] = ['用户','日期','时间段','高压','低压','心跳','备注'];
    }
  • 按表头顺序写入数组
//导出列表 按表头添加到列表
    list.forEach((element) =>{
        let arrInner = [];
        if(userAdmin === true){
            arrInner.push(element.userAccount);
        }
        arrInner.push(formatTimestamp(element.recordDate));
        arrInner.push(bpNumberToTag(element.timeTag));
        arrInner.push(element.sys);
        arrInner.push(element.dia);
        arrInner.push(element.pul);
        arrInner.push(element.note);

        data.push(arrInner);
    });
  • 后端
  1. 工具类将文件转为Buffer
//导出excel 文件名格式 用户名数据类当前时间
const toExcelFile = (fileName,data) =>{
    //后端生成excel成功
    const buffer = xlsx.build([{name: fileName, data: data}]); //生成数据流
    return buffer;
}

2.后端路由处理 返回的body必须只有文件的数据流否则会损坏

/* 
    响应体设置
    */
    // request.headers['content-disposition'] = `attachment; filename=${fileName}`; //设置文件名
    //前端允许Content-Disposition
    ctx.set("Access-Control-Expose-Headers", "Content-Disposition"); 
    //设置文件名
    ctx.attachment(Buffer.from(fileName).toString('base64')); 
    ctx.body = toExcelFile(fileName ,data); //buffer文件流

屏幕截图-2022-04-23-164708

2.数据导出

前端将数据流arraybuffer转为结合a标签进行下载。由于涉及到响应头而且不能用自己封装result方法,就重新封装了一个下载文件的函数

export const downloadExcel = (url,data) =>{
    //请求数据流
    return axios.post(getURL(url) , data , {
        headers : getHeaders(),
        responseType: 'arraybuffer',
    }).then((res)=>{
    //处理数据流并下载
        // console.log(res);
        //arraybuffer 转为Blob
        let blob = new Blob([res.data],{type:'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'});
        //文件名获取它的类型是buffer(为了传输中文)
        const fileName =  res.headers['content-disposition'].split(';')[1].split('filename=')[1]
        //a标签模拟点击
        const link = document.createElement('a');
        link.style.display = 'none';
        link.href = URL.createObjectURL(blob);//创建url对象
        link.download = Buffer.from(fileName,'base64').toString(); //文件名buffer转string
        document.body.appendChild(link);
        link.click();
        document.body.removeChild(link);
        URL.revokeObjectURL(link.href);//销毁url对象
    });
};

参考连接

  1. node 读取目录 创建excel输出目录名称_脑瓜不疼的博客-CSDN博客_node 创建excel
  2. vue导出excel表格-后端返回blob流文件,前端接收并导出下载(处理导出以后打开文件损坏问题) - 掘金
  3. axios里的responseType - 简书
  4. koa框架koa-static配置静态目录获取图片_我坑我承认的博客-CSDN博客_koa 获取图片
  5. 【egg】ctx.attachment的意义 - 简书
  6. 解决 在koa 中 给 cookie 中存入 汉字产生的问题_yunchong_zhao的博客-CSDN博客