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}};
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');
});
问题:不想读写文件
- 我是用
node-xlsx
这个包来生成excel的,本来想着生成一个文件再用express自带的res.download()直接下的,结果node-xlsx
直接返回了一个buffer,这就得重新考虑一下了。 - 最容易想到的下载方式是,把这个buffer写到一个临时文件夹里,再进行下载。但是转念一想不对啊,我本来就在内存里生成的,干嘛要写到文件里再读出来呢?
方法:buffer转成stream输出
设置http响应头
- 拿个文件试了一下
res.download()
,发现它在http响应的headers里设置了Content-Type
和Content-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 就是两个一起写的