从Node.js通过Restify发送到客户端时XLSX文件损坏 [英] XLSX File corrupted when sent from Node.js via Restify to Client

查看:212
本文介绍了从Node.js通过Restify发送到客户端时XLSX文件损坏的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在一个项目中,我正在使用XLSX node.js库创建一个excel文件,并通过Restify将其发送到客户端,然后再使用FileSaver.js库将其保存到本地计算机上.当我将xlsx工作簿写入后端文件时,它可以很好地打开,但是,当我在客户端上打开它时,它已损坏.我收到错误消息:"Excel无法打开该文件.文件格式或文件扩展名无效.请验证文件未损坏,并且文件扩展名与文件格式匹配."

I am working on a project where I am creating an excel file using XLSX node.js library, sending it to a client via Restify where I then use the FileSaver.js library to save it on the local computer. When I write the xlsx workbook to file on the backend, it opens fine, however, when I open it on the client, it is corrupted. I get the error: "Excel cannot open this file. The file format or file extension is not valid. Verify that the file has not been corrupted and that the file extension matches the format of the file".

这是我用于在后端写入和发送文件的代码:

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

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

在前端,我正在使用XLSX文档中的代码:

On the front end, I am using 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 would not work? Any help would be much appreciated. Thanks.

推荐答案

正如评论中的Luke所述,您必须在发送缓冲区之前执行base64编码.这是使用NPM模块的代码段 node-xlsx .

As Luke mentioned in the comments, you have to do a base64 encoding before sending the buffer. Here's a snippet that used the NPM module 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的前端代码:

And this is the frontend code using 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;
    }
  }
})

这篇关于从Node.js通过Restify发送到客户端时XLSX文件损坏的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆