使用node-xlsx实现导入下载excel文件

需求

将一些后台的数据导出为excel文件,方便查看和保存为本地文档

实现思路

node-xlsx模块提供了excel文件解析器和构建器
可以通过xlsx.build构建xlsx文件(就是将数据转为excel)

  1. 下载node-xlsx模块:
cnpm install node-xlsx --save
  1. node.xlsx的简单使用
let buffer = xlsx.build( [ { name:"name", data:"data"} ] )
data = [
  {
    name: "第1个工作薄的名称如:sheet", 
    data: [
      ["第1行第1列的数据", "第1行第2列的数据", "第1行第3列的数"],
      ["第2行第1列的数据", "第2行第2列的数据", "第2行第3列的数据"]
    ],
  },
  {
    name: "第2个工作薄的名称如:sheet", 
    data: [
      ["第1行第1列的数据", "第1行第2列的数据", "第1行第3列的数"],
      ["第2行第1列的数据", "第2行第2列的数据", "第2行第3列的数据"]
    ],
  }
]

同时,node-xlsx也可以解析excel

xlsx.parse(filepath,{otherOptions})
  1. node-xlsx构建xlsx文件
//引入生成excel的依赖包
const xlsx = require("node-xlsx");
let fs = require("fs");
const list = [
  {
    name: "sheet", // 工作薄的名称
    data: [
      ["第1行第1列", "第1行第2列", "第1行第3列"],
      ["第2行第1列", "第2行第2列", "第2行第3列"]
    ],
  },
  // 如果多个工作薄, 就是多个对象。格式如上
];
// 使用提供的构建 xlsx 文件的方法
const buffer = xlsx.build(list);
fs.writeFile("导出excel的名称.xlsx", buffer, function (err) {
  if (err) {
    console.log(err, "导出excel失败");
  } else {
    console.log("导出excel成功!");
  }
});
  1. 如何设置列宽
    我们可以通过配置项 sheetOptions 来处理
    通过 xlsx.build 的第2个参数来处理
const sheetOptions = {'!cols': [{wch: 20}, {wch: 30}]}; //设置宽度
let buffer=xlsx.build([{name: 'mySheetName',data: data}],{sheetOptions});

代码实现(一)

后端返回excel文件路径,前端通过window.open()的方式打开

  • 先建util文件夹中创建excel.js,封装导出excel文件功能
var fs = require('fs')
var dayjs = require('dayjs')
var xlsx = require('node-xlsx')

module.exports = (list,titleList,keyList)=>{
  let data = []
  data.push(titleList)// 将标题行(Excel表格的列标题)添加到数据数组中。
  list.map(o=>{
    let item = []
    keyList.forEach(p=> item.push(o[p]))
    data.push(item)
  })
  // 定义一个包含Excel表格选项的对象,其中'!cols'指定列的宽度,这里设置了四列,分别为20、10、20、20的宽度。
  let sheetOptions = {'!cols': [{wch: 20}, {wch: 20}, {wch: 20}, {wch: 20}]};
  let buffer = xlsx.build([{name: 'grade', data: data}], {sheetOptions}); 

  let file = `export/${dayjs().format('YYYYMMDDhhmmss')}.xlsx`
  fs.writeFileSync(file, buffer, {'flag':'w'})// 以写入模式打开文件,如果文件不存在则创建,如果文件存在则截断文件。

  return file
}
  • 后端路由
// 导出导师选择信息excel文件
router.post("/techAndStudExport", async (req, res,next) => {
  let params = req.body
  let sql = `CALL PROC_STUDANDTECH_INFO()`
  let r = await callP(sql,params,res)
  console.log(r)
  let title = ['班级',"学号","姓名","导师名称"]
  let key = ["class","student_name",'student_uid',"teacher_name"]
  let path = exportExcel(r,title,key)
  res.status(200).json({code:200, path:path})
})
  • 前端调用接口并实现下载
  // 导出数据按钮
  const doExport = async(e)=> {
    let path = await store.exportTechAndStud()
    window.open(`${API_SERVER}/${path}`)
  }

代码实现(二)

通过blob文件流的形式传递给前端
代码日后实现


两种方式的对比

  1. 前端通过open或location.href的方式实现下载
window.open('downloadFile.zip');

location.href = 'downloadFile.zip';

优点

  • 简单直接

缺点

  • 不能下载浏览器可以直接浏览的文件类型,如txt、png、jpg等
  • 不能添加header,不能进行鉴权
  • 有些浏览器会拦截下载
  1. 利用Blob对象
    通过发送ajax请求api获取文件流进行下载。毕竟有些时候,后端不会直接提供一个下载地址给你直接访问,而是要调取api

进行下载的思路很简单
1. 发请求获取二进制数据,转化为Blob对象
2. 利用URL.createObjectUrl生成url地址
3. 赋值在a标签的href属性上,结合download进行下载。

优点

  • 能解决浏览器可浏览的文件不能下载的问题
  • 可设置header,可以添加鉴权信息
    缺点
  • 兼容性问题,IE10以下不可用;Safari浏览器可以留意下使用情况
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值