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 就是兩個一起寫的