Take data from an xlsx file

Asked

Viewed 68 times

1

I am trying to make a code that reads the data of an excel file and write them on the console. For this I am using the Sheetjs but I’m having a problem. Every time my code returns "Undefined" on my console, unless I put the console.log within the onreadystatechange, but in no way does this Arrow Function return me the data from the xlsx file. What am I missing?

var pega_dados_excel = () => {
    var softwares_instalados;

    var url = "test.xlsx"; // Inserir o nome do Arquivo excel(xls ou xlsx)

    var req = new XMLHttpRequest(); // Inicia a requisição
    req.open("GET", url, true);
    req.responseType = "arraybuffer";
    
    req.onreadystatechange = function(){
        var data = new Uint8Array(req.response);
        var workbook = XLSX.read(data, { type: "array" });
        var first_sheet_name = workbook.SheetNames[0];
        var worksheet = workbook.Sheets[first_sheet_name];
        
        softwares_instalados = (XLSX.utils.sheet_to_json(worksheet));
    }

    req.send();

    return softwares_instalados;
}

$(document).ready(function () {
    console.log(pega_dados_excel());
});

EDIT1: After the change made, suggested by the Cardinal Cmte the island was as follows:

inserir a descrição da imagem aqui

1 answer

0


I think the problem is because the onreadystatechange is asynchronous, meaning your code will run from top to bottom synchronously, while the onreadystatechange it will take a while to be called, soon your softwares_instalados will be undefined always, because before the onreadystatechange be called, the function has already given the return of softwares_intalados.

My tip would be to maybe work with a function of callbackpassed by parameter to your function pega_dados_excel (var pega_dados_excel = (callback) => {...}), which will be executed when the asynchronous operation ends. When this callback is executed, we will pass the results as parameter to it. In this case I called softwares and we will pass on the result (softwares_instalados) for her.

I’ll show you some code that might work. IF IT WORKS, comment on my answer so I can explain it to you, but I think the code speaks for itself:

var pega_dados_excel = (callback) => {
  var softwares_instalados;

  var url = "test.xlsx"; // Inserir o nome do Arquivo excel(xls ou xlsx)

  var req = new XMLHttpRequest(); // Inicia a requisição
  req.open("GET", url, true);
  req.responseType = "arraybuffer";
  
  req.onreadystatechange = function(){
      var data = new Uint8Array(req.response);
      var workbook = XLSX.read(data, { type: "array" });
      var first_sheet_name = workbook.SheetNames[0];
      var worksheet = workbook.Sheets[first_sheet_name];
      
      softwares_instalados = (XLSX.utils.sheet_to_json(worksheet));

      // quando tivermos uma resposta, executamos a funcao de callback.
      callback(softwares_instalados) 
  }

  req.send();
}

$(document).ready(function () {
  // dentro de 'pega_dados_excel', vamos executar nossa funcao de callback
  // repare que 'softwares' é o parametro que passamos para 
  // 'callback(softwares_instalados)'

  pega_dados_excel((softwares) => {
    console.log(softwares) // quando tivermos o retorno, damos um console.log()
  });
});

Try to test this script I put in. If it works I can explain, if not, I delete my answer and think a little more about the solution. I hope I’ve helped.

  • Thank you very much, I understood how you did and worked on my test, but is being returned 3 console.log, being two voids and the last correctly, can you tell me why ? I will leave a print on the question

  • how’s your code? can I take a look.

  • I updated the code on the question

  • ah yes, the explanation is because of the readyState of the document, I believe. as it shows the documentation of Mozilla, "It returns "loading" while Document is loading, "Interactive" when it was loaded but its sub-resources (like images, for example) not yet, and "complete" when it was fully loaded." So there are 3 different stages, and therefore the 3 console.log(). If your question has been answered, return the code of your question to how it was initially and a vote if my answer was useful :D

  • 1

    It makes sense... I put an if inside the onreadystatechange to check if it is already OK and worked perfectly. the if stayed so: if (this.readyState == 4 && this.status == 200). Thank you so much for your help :)

Browser other questions tagged

You are not signed in. Login or sign up in order to post.