我正在开发一个项目,我正在使用XLSX node.js库创建一个excel文件,通过Restify将其发送到客户端,然后我使用FileSaver.js库将其保存在本地计算机上。当我将xlsx工作簿写入后端文件时,它打开正常,但是,当我在客户端打开它时,它已损坏。我收到错误:" Excel无法打开此文件。文件格式或文件扩展名无效。验证文件是否已损坏,文件扩展名是否与文件格式相符"。
以下是我在后端编写和发送文件的代码:
var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
var workbook = xlsx.write(wb, wopts);
res.send(200, workbook);
在前端,我使用的是XLSX文档中的代码:
function s2ab(s) {
var buf = new ArrayBuffer(s.length);
var view = new Uint8Array(buf);
for (var i=0; i!=s.length; ++i)
view[i] = s.charCodeAt(i) & 0xFF;
return buf;
}
saveAs(new Blob([s2ab(response.data)],{type:""}), "test.xlsx");
有关为什么这不起作用的任何想法?任何帮助将非常感激。感谢。
答案 0 :(得分:3)
正如Luke在评论中提到的,你必须在发送缓冲区之前进行base64
编码。以下是使用NPM模块node-xlsx
的代码段。
var xlsx = require('node-xlsx');
router.get('/history', function (req, res) {
var user = new User();
user.getHistory(req.user.userId, req.query.offset, req.query.limit)
.then(function (history) {
if (req.headers.contenttype && req.headers.contenttype.indexOf('excel') > -1) {
var data = [['Data', 'amount'], ['19/12/2016', '10']];
var xlsxBuffer = xlsx.build([{ name: 'History', data: data }]);
res.end(xlsxBuffer.toString('base64'));
} else {
res.send(history);
}
})
.catch(function (err) {
res.status(500).send(err);
});
});
这是使用Angular的前端代码:
$scope.getXlsFile = function() {
var config = {
params: {
offset: $scope.offset,
limit: $scope.limit
},
headers: {
'contentType': 'application/vnd.ms-excel',
'responseType': 'arraybuffer'
}
};
$http.get('/api/history', config)
.then(function(res) {
var blob = new Blob([convert.base64ToArrayBuffer(res.data)]);
FileSaver.saveAs(blob, 'historial.xlsx');
})
}
其中convert
是以下工厂:
.factory('convert', function () {
return {
base64ToArrayBuffer: function (base64) {
var binary_string = window.atob(base64);
var len = binary_string.length;
var bytes = new Uint8Array(len);
for (var i = 0; i < len; i++) {
bytes[i] = binary_string.charCodeAt(i);
}
return bytes.buffer;
}
}
})