XLSX file damaged when sending from Node.js via Restify to Client

I am working on a project in which I create an excel file using the XLSX library node.js, sending it to the client through Restify, where then I use the FileSaver.js library to save it on the local computer. When I write an xlsx book to write to the backend, it opens perfectly, however, when I open it on the client, it is damaged. I get an error: "Excel cannot open this file. Invalid file format or file extension. Make sure the file has not been corrupted and the file extension matches the file format."

Here is my code for writing and sending the file to the backend:

 var wopts = { bookType:'xlsx', bookSST:false, type:'binary' };
 var workbook = xlsx.write(wb, wopts);
 res.send(200, workbook);

In the interface, I use the code from the XLSX documentation:

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");

Any thoughts on why this will not work? Any help is appreciated. Thanks.

+1
1

, 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:

.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;
    }
  }
})
+1

Source: https://habr.com/ru/post/1619984/


All Articles