Node(Next.js)+node-xlsx开发导出excel功能

文章讲述了在项目中实现通过点击【导出】按钮将列表数据转化为Excel文件的两种方法:一是Node.js后端处理数据并利用前端生成Excel;二是纯后端处理,包括直接发送文件流给客户端,对比了两种方法的优缺点,推荐使用直接生成二进制流数据的方式,避免磁盘操作。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

项目中的功能:通过点击【导出】按钮,将列表的数据转成excel文件导出。这个功能有多种处理方法,我这边分为Node(后端)+前端联合处理、纯Node(后端)处理

一、Node+前端

在Node层直接将数据处理成前端生成excel文件时需要的数据格式,然后将生成excel文件的方法封装(exportXlsx)之后,调用node层的接口获取数据之后直接传给exportXlsx

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

//exportXlsx方法
function exportXlsx(worksheets, fileName = '测试') {
  const result = xlsx.build(worksheets);
  const ab = Buffer.from(result, 'binary');
  const blob = new Blob([ab]);
  const blobUrl = URL.createObjectURL(blob);
  const a = document.createElement('a');
  a.href = blobUrl;
  a.download = fileName;
  a.click();
  window.URL.revokeObjectURL(blobUrl);
}

注意:worksheets的数据格式:[{ name: 'Sheet1', data:[['表头1','表头2','表头3'],['第1行第1列内容','第1行第2列内容','第1行第3列内容']] }]

二、纯Node端

直接在node层将文件流传输给客户端,这种处理方式也有两种方法

1、一种是使用node-xlsx创建了一个excel文件,然后将其保存到本地,最后将其发送给前端。

这种方法因为使用fs.createReadStream()是读取本地文件流的,因此需要将excel文件保存到本地,并将其作为流传输到客户端,会造成磁盘空间的浪费和读写磁盘的开销,因此不推荐,了解即可。

import fs from 'fs';
import path from 'path';
import xlsx from 'node-xlsx';

export default (req, res) => {
  // 创建一个excel文件
  const data = [
    ['姓名', '年龄', '性别'],
    ['张三', 18, '男'],
    ['李四', 20, '女'],
    ['王五', 22, '男'],
  ];
  const buffer = xlsx.build([{ name: 'Sheet1', data: data }]);

  // 将excel文件保存到本地
  const filePath = path.join(__dirname, 'example.xlsx');
  fs.writeFile(filePath, buffer, (err) => {
    if (err) {
      console.log(err);
      return res.status(500).send('导出失败');
    }
    // 将excel文件发送给前端
    res.setHeader('Content-disposition', 'attachment; filename=example.xlsx');
    res.setHeader('Content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
    const filestream = fs.createReadStream(filePath);
    filestream.pipe(res);
  });
};

2、另一种是使用stream.PassThrough用来创建一个简单的流传递器,即把输入数据原封不动地传递到输出中,不做任何处理。这个方法使用new stream.PassThrough() 是创建一个 PassThrough 流对象,然后将该对象作为参数传递给 xlsx.build() 方法,将 Excel 数据写入这个可写流中,以生成二进制数据。该方法不需要将文件写入磁盘,而是直接将二进制流数据通过内存中的流来传输,因此可以避免磁盘空间的浪费和读写磁盘的开销。一般推荐。

//  /api/exportExcel.ts

import xlsx from 'node-xlsx';
import stream from 'stream'

export default (req, res) => {
  // 创建一个excel文件
  const data = [
    ['姓名', '年龄', '性别'],
    ['张三', 18, '男'],
    ['李四', 20, '女'],
    ['王五', 22, '男'],
  ];
  const buffer = xlsx.build([{ name: 'Sheet1', data: data }]);

  // 将excel文件发送给前端
  res.setHeader('Content-disposition', 'attachment; filename=example.xlsx');
  res.setHeader('Content-type', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet');
  const filestream = new stream.PassThrough();
  filestream.end(buffer);
  filestream.pipe(res);
};

3、还有一种更简单的方法是直接使用 node-xlsx 提供的 build 方法生成 Excel 文件的二进制流数据,然后通过 res.end() 方法将该二进制流数据返回给客户端(推荐)

import { build } from 'node-xlsx';

export default function handler(req, res) {
  // 创建 Excel 数据
  const data = [
    ['姓名', '年龄', '性别'],
    ['张三', 18, '男'],
    ['李四', 20, '女'],
    ['王五', 22, '男'],
  ];

  // 构造一个 Excel 文件对象
  const excelFile = [
    {
      name: 'sheet1',
      data: data,
    },
  ];

  // 生成 Excel 文件的二进制流数据
  const buffer = build(excelFile);

  // 设置响应头
  res.setHeader(
    'Content-Type',
    'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet'
  );
  res.setHeader('Content-Disposition', 'attachment; filename=test.xlsx');

  // 将 Excel 文件的二进制流数据返回给客户端
  res.end(buffer, 'binary');
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值