简体   繁体   中英

NodeJs/Express writing xlsx-template and sending it back for browser download

I have this excel where i want to replace the scalar values as the xlsx-template docs say:

| Extracted on: | ${extractDate} | and I want to send it over the response object. The file gets written correctly in the output path but in the client it gives me a binary output. Bellow is the backend call to the Url

this.downloadSheet = async (req, res) => {

    let seriesNumber = Number(req.body.seriesNumber);
    let sheetPath = path.resolve('../filePath/excel.xlsx');
    let sheetFinalOuput = path.resolve('../filePath/excelOutput.xlsx');
    #Get data needed to swap for the excel
    let excelDataStream = await ReportService.getBalanceSheetAllInOne(balanceSheetPath, seriesNumber);
    fs.readFile(path.resolve(balanceSheetPath), function(err, data) {
      // Create a template
      let template = new XlsxTemplate(data);

      // Replacements take place on first sheet
      const sheetNumber = 1;

      // Perform substitution
      template.substitute(sheetNumber, excelDataStream);

      // Get binary data
      var mydata = template.generate({ type: 'nodebuffer'});

      fs.writeFile(path.resolve(balanceSheetFinalOuput), mydata, function(err) {
        if(err) {
          return console.log(err);
        }
        console.log(`Wrote data in file, check please!`);

        // Send File & set headers
        res.set({'Content-Disposition': `attachment; filename=balanceIncome${seriesNumber}.csv`, 'Content-Type': 'text/csv'});
        res.write(mydata);
        res.end();
      });
    });
  };

client function http post request

$http.post(`${settings.apiHost}/api/panel/report/balanceSheet/allInOne/false`,{seriesNumber: $scope.seriesNumber})
        .success(function (response) {
          var file = new Blob([response], {type: 'text/csv'});

          var isGoogleChrome = window.chrome != null && window.navigator.vendor === "Google Inc.";
          var isIE = /*@cc_on!@*/false || !!document.documentMode;
          var isEdge = !isIE && !!window.StyleMedia;


          if (isGoogleChrome){
            var url = window.URL || window.webkitURL;

            var downloadLink = angular.element('<a></a>');
            downloadLink.attr('href',url.createObjectURL(file));
            downloadLink.attr('target','_self');
            downloadLink.attr('download', `balanceSheet_${$scope.seriesNumber}.csv`);
            downloadLink[0].click();
          }
          else if(isEdge || isIE){
            window.navigator.msSaveOrOpenBlob(file,`balanceSheet_${$scope.seriesNumber}.csv`);

          }
          else {
            var fileURL = URL.createObjectURL(file);
            window.open(fileURL);
          }
        })

client side

const url = `${settings.apiHost}/api/panel/report/balanceSheet/allInOne/false/${$scope.seriesNumber}`;
window.open(url);

server side(change router params and method to GET)

let seriesNumber = Number(req.params.seriesNumber);
... 
fs.writeFile(path.resolve(balanceSheetFinalOuput), mydata, function(err) {
  if(err) {
    return console.log(err);
  }
  console.log(`Wrote data in file, check please!`);

  // Send File & set headers
  res.set({'Content-Disposition': `attachment; filename=balanceIncome${seriesNumber}.csv`, 'Content-Type': 'text/csv'});
  res.send(mydata);
});

another way

client side

...
.success(function (nodeBuffer) {
  let arraybuffer = Uint8Array.from(nodeBuffer).buffer;
  var file = new Blob(arraybuffer, {type: 'text/csv'});
  ....
}

server side

...
fs.writeFile(path.resolve(balanceSheetFinalOuput), mydata, function(err) {
  if(err) {
    return console.log(err);
  }
  console.log(`Wrote data in file, check please!`);
  res.send(mydata);
});
...

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM