Visual Builder

Get Involved. Join the Conversation.

Topic

    Cesar Tepetla Corte
    Read to CSV file using file pickerAnswered
    Topic posted April 24, 2019 by Cesar Tepetla CorteBronze Medal: 1,250+ Points, tagged Custom Code, Database, JET, Style, UI, Validation 
    165 Views, 8 Comments
    Title:
    Read to CSV file using file picker
    Summary:
    Read to CSV file using file picker
    Content:

    Hi everyone,

    I have to use the file selector to read a csv file and then insert it into a database.

    The <oj-file-picker> component is displayed and allows you to select a file, but I do not know how to perform the reading

    Any comments or help is appreciated

    Best Comment

    Duncan Mills

    You can use the HTML 5 File API to do this. Here's an example Page Module function that reads a text file 

    define([], function() {
      'use strict';
    
      var PageModule = function PageModule() {};
      
      PageModule.prototype.processCSVFile = function(uploadedFiles){
        //in this case only process the first file because I've set single selection on the picker 
        var csvFile = uploadedFiles[0];
        console.log('Processing file: '+ csvFile.name + ' Type is '+ csvFile.type);
        if (csvFile.type === 'text/csv') {
          var fileReader = new FileReader();
          fileReader.onload = function(fileReadEvent){
             var allTextContents = fileReadEvent.target.result;
            //Parse the text here
            ...
          };
          fileReader.readAsText(csvFile);
        }
    
      };
    
      return PageModule;
    });
    

     

     

     Here are the high level steps:

    1) Create the oj-file-picker on the page (I assume you have this)

    2) Add an Action Chain to the ojSelect event on the picker via the property inspector this will automatically pass the event detail into the chain for you

    4) In the action chain add a Call Module Function Action and wire it to the processCSVFile method defined in the Page Module

    5) Set the uploadedFiles parameter for that function to $chain.variables.detail.files

    That's it.  You can then process the Text data and parse it as you wish. You can also read the text file in chunks if it is large just have a search for HTML 5 File API for examples

    Comment

     

    • Duncan Mills

      You can use the HTML 5 File API to do this. Here's an example Page Module function that reads a text file 

      define([], function() {
        'use strict';
      
        var PageModule = function PageModule() {};
        
        PageModule.prototype.processCSVFile = function(uploadedFiles){
          //in this case only process the first file because I've set single selection on the picker 
          var csvFile = uploadedFiles[0];
          console.log('Processing file: '+ csvFile.name + ' Type is '+ csvFile.type);
          if (csvFile.type === 'text/csv') {
            var fileReader = new FileReader();
            fileReader.onload = function(fileReadEvent){
               var allTextContents = fileReadEvent.target.result;
              //Parse the text here
              ...
            };
            fileReader.readAsText(csvFile);
          }
      
        };
      
        return PageModule;
      });
      

       

       

       Here are the high level steps:

      1) Create the oj-file-picker on the page (I assume you have this)

      2) Add an Action Chain to the ojSelect event on the picker via the property inspector this will automatically pass the event detail into the chain for you

      4) In the action chain add a Call Module Function Action and wire it to the processCSVFile method defined in the Page Module

      5) Set the uploadedFiles parameter for that function to $chain.variables.detail.files

      That's it.  You can then process the Text data and parse it as you wish. You can also read the text file in chunks if it is large just have a search for HTML 5 File API for examples

    • Cesar Tepetla Corte

      Hi Duncan,

      I have tried the method that you shared but it has not worked yet, I have created a method to read text files only and this one has worked.

      PageModule.prototype.processCSVFile = function(uploadedFiles){
          var fileDisplayArea = document.getElementById('oj-text-area-1084591017-1');
          var file = uploadedFiles.files[0];
      var textType = /text.*/;
       
      if (file.type.match(textType)) {
      var reader = new FileReader();
       
      reader.onload = function(e) {
      fileDisplayArea.innerText = reader.result;
      }
       
      reader.readAsText(file);
      } else {
      fileDisplayArea.innerText = "File not supported!";
      }
        };
       
      but now I want to change the validation to only accept CSV files but I can not get it to work,
       
      Regards.
    • Duncan Mills

      if you set the accept attribute of the file picker to the following it should work: 

      accept='{{["text/csv"]}}'
      

      Note that is is passed as an array which might be what you where missing?

       

      • Cesar Tepetla Corte

        I think that nothing was missing but I found some things, for example, put the function as you indicated in step 5 $ chain.variables.detail.files but that also made it not work when I stayed this way $ chain.variables.detail Finally, I did not know why the IF condition does not work (csvFile.type === 'text / csv') I have only left the reading code even if I accept any file.

        What I am trying to do now is to return the contents of the file in a variable I am currently showing it in a text area with this line fileDisplayArea.innerText = reader.result; but I want to pass it to a variable how could I do that ???

        I appreciate your comments.

    • Duncan Mills

      To get the file contents back into a variable you need to return it from the page function and then you can assign the result of the function to a VBCS variable using a Assign Variable Action. 

      Now it's not as simple as just putting a return statement in the reader.onload function as that happens asynchronously - However, you can return a promise from your page module function and pass the data back asynchronously once it is done - the action chain will wait. 

      I can build you a trivial sample tomorrow and upload it

    • Duncan Mills

      Written up in detail here:

      https://blogs.oracle.com/groundside/uploading-and-reading-a-text-file-in-visual-builder