Search code examples
node.jsazure-blob-storagenode.js-stream

Download a excel file from azure blob and process its data without needing to save file to local directory


I want to download an excel file from azure blob and process it's data using the 'xlsx' npm module. I have achieved this with saving the file to local directory on my node.js server.

But I have to Implement this without needing to save the file locally on server.

How do I achieve this ?

Following is my js file using - download to local directory method.

const xlsx = require('xlsx');

  const azureStorageConfig = {
  accountName: "",
  accountKey: "",
  blobURL: "",
  containerName: "test-container"
};

let fileName = "test_blob.xlsx";

const downloadBlob = async (blobName, downloadFilePath) => {
  return new Promise((resolve, reject) => {
    const name = path.basename(blobName);
    const blobService = azureStorage.createBlobService(azureStorageConfig.accountName,azureStorageConfig.accountKey); 
    blobService.getBlobToLocalFile(azureStorageConfig.containerName,blobName,`${downloadFilePath}${name}`, function(error, serverBlob) {
        if (error) {
            reject(error);
        } else {
            resolve(downloadFilePath);
        }
    });
  });
};

downloadBlob(fileName,'./local_dir/').then((downloadFilePath)=>{
  parseExcel(downloadFilePath + fileName);
});

const parseExcel = function(downloaded_file_path){
  let workbook = xlsx.readFile(downloaded_file_path);
  // Parse further
}

How this code will change when following a process which does not require saving the file to local directory ?


Solution

  • As reference for you, here is my idea with sample code for your needs, as below.

    1. Generate a blob url with SAS token

      var azure = require('azure-storage');
      var accountName = '<your account name>';
      var accountKey = '<your account key>';
      var blobService = azure.createBlobService(accountName, accountKey);
      
      var containerName = 'test-container';
      var blobName = 'test_blob.xlsx';
      
      var startDate = new Date();
      var expiryDate = new Date(startDate);
      expiryDate.setMinutes(startDate.getMinutes() + 100);
      startDate.setMinutes(startDate.getMinutes() - 100);
      
      var sharedAccessPolicy = {
        AccessPolicy: {
          Permissions: azure.BlobUtilities.SharedAccessPermissions.READ,
          Start: startDate,
          Expiry: expiryDate
        }
      };
      
      var token = blobService.generateSharedAccessSignature(containerName, blobName, sharedAccessPolicy);
      var sasUrl = blobService.getUrl(containerName, blobName, token);
      
    2. Read blob body bytes via request, then to use XLSX.read(data, read_opts) to parse blob body as Uint8Array.

      var request = require('request');
      var XLSX = require('xlsx');
      request(sasUrl, {encoding: null}, function (error, response, body) {
        var workbook = XLSX.read(body, {type:"buffer"});
        console.log(workbook.Sheets.Sheet1);
      });
      

    Hope it helps.