express下载excel

本文分享了使用Node.js和node-xlsx包生成并下载Excel文件的实战经验,包括避免文件读写,直接通过内存操作生成Excel,以及如何正确设置HTTP响应头确保文件正确下载。

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

update

  • 靠,不用转stream的,res.send()能直接发buffer的… …

  • 用node写了个查询数据生成和下载excel的功能,踩了些坑,记一下
  • 先贴个例子
app.get('/download', function (req, res, next) {
  let data = [[1, 2, 3], [true, false, null, 'sheetjs'], ['foo', 'bar', new Date('2014-02-19T14:30Z'), '0.3'], ['baz', null, 'qux']];
  let range = {s: {c: 0, r:0 }, e: {c:0, r:3}}; // A1:A4
  let option = {'!merges': [ range ]};

  let buffer = xlsx.build([{name: "mySheetName", data: data}], option);
  
  let filename = '测试编码.xlsx';
  filename = urlencode(filename);

  res.set({
    'Content-Type': 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet',
    'Content-Disposition': `filename=${filename}`,
    'Content-Length': buffer.length
  });
	res.send(buffer,'binary');
	//不用转stream
	//let bufferStream = new stream.PassThrough();
	//bufferStream.end(buffer);
	//  bufferStream.pipe(res);
});

问题:不想读写文件

  • 我是用node-xlsx这个包来生成excel的,本来想着生成一个文件再用express自带的res.download()直接下的,结果node-xlsx直接返回了一个buffer,这就得重新考虑一下了。
  • 最容易想到的下载方式是,把这个buffer写到一个临时文件夹里,再进行下载。但是转念一想不对啊,我本来就在内存里生成的,干嘛要写到文件里再读出来呢?

方法:buffer转成stream输出

  • 再看看express自带的方法res.download()是怎么做的,它是对res.sendFile()的一个封装,需要读取文件的路径。但下载文件并不止这一种方法,还可以使用的方式进行传输,将buffer转成stream直接输出到响应当中就不需要经过文件的中转了。
  • 接着我就在node的文档里看到这个函数:fs.createReadStream(path[, options]),path的签名长这样path <string> | <Buffer> | <URL>,把这个buffer传进去产生stream,再stream.pipe(res)问题不就解决了?事实证明我还是图样。。。
  • 可能是我对这个函数的理解出了一些偏差,createReadStream这个函数把buffer传进去直接就报错了,它只要字符串格式的参数。那就换一种把buffer转stream的写法呗
    let bufferStream = new stream.PassThrough();
    bufferStream.end(buffer);
    bufferStream.pipe(res);
    
  • 这次运行倒是没问题,问题是下载下来的的文件居然是个download.zip,这是个什么鬼?还解压出来一堆xml。。。
  • 等等,我目前还没有设置过文件名和扩展名吧,那浏览器要怎么识别出来这是个什么文件呢?难怪会出问题。对于如何解决,这有一份现成的参考,res.download()不就能好好的传文件过来了?

设置http响应头

  • 拿个文件试了一下res.download(),发现它在http响应的headers里设置了Content-TypeContent-Disposition用以描述文件的类型和名称,我也依样画葫芦设置了这几个属性,总算是能正常下载了。
  • 还得注意一点,http header 里面是不支持中文编码的,要用urlencode把中文转成%E6%B5%8B这样的字符串才能用

http 响应头

  • Content-Type 指定http协议中的媒体类型(MIME)
    • 常见的有html:text/html 、文本:text/plain之类的。xlsx格式的excel对应的是application/vnd.openxmlformats-officedocument.spreadsheetml.sheet
  • Content-Disposition 指示响应的内容该以怎样的形式展示
    • attachment : 表明是否是附件,带上它就会弹出下载对话框。虽然excel不用这个也是弹出对话框,但是对那些浏览器可以直接打开的文件,比如html,jpg之类的来说,带上这个参数弹出下载框,不带就直接在浏览器上显示了
    • filename : 文件名
    • filename* :也是文件名,这是考虑到兼容性 (IE) 的写法。如果二者同时存在且浏览器支持的话,会优先采用 filename*。res.download 就是两个一起写的
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值