Another Salesforce blog!!!

Salesforce, Apex

Lightning Aura Component CSV Uploader

Uploading the CSV file and view the output using Aura Component.

Component:

<aura:component controller="csvController">
    <aura:attribute
                    name="TableContent"
                    type="String"
                    description=" Show the Result class"
                    />
    <aura:attribute
                    name="TargetFileName"
                    type="String"
                    description="Name of the file"
                    />
    <aura:attribute name="tableheaders" type="Object[]" />
    <aura:attribute name="fileContentData" type="String" />
    
    <!-- It will display 100 records . Change for your requirement-->
    <aura:attribute name="NumOfRecords" type="Integer" default="100" />
    <aura:attribute name="showMain" type="Boolean" default="true" />
    <aura:attribute name="fileName" type="String" default="No File Selected.." />
    
  <!-- Design enabled attributes -->
  <aura:attribute
    name="buttonLabel"
    type="string"
    default="Upload File"
    access="global"
    description="The label of the button."
  />
  <aura:attribute
    name="disabled"
    type="Boolean"
    default="false"
    access="global"
  />
  <div class="slds-form-element" aura:id="form-container">
    <!-- Outer form label -->
    <span class="slds-form-element__label" id="file-selector-primary-label"
      >{!v.formLabel}</span
    >
    <div class="slds-form-element__control">
      <div class="slds-file-selector slds-file-selector_files slds-is-relative">
        <!-- Loading indicator -->
        <aura:if isTrue="{!v.loading}">
          <lightning:spinner
            alternativeText="Loading"
            size="small"
            variant="brand"
          />
        </aura:if>

        <div
          class="slds-m-around--large"
          ondragover="{!c.onDragOver}"
          ondrop="{!c.onDrop}"
        >
          <!-- Input -->
          <!-- Lightning Input with file type and on file change call the 'handleFilesChange' controller -->
          <lightning:input
            aura:id="fuploader"
            onchange="{!c.onchange}"
            type="file"
            name="file"
            label="Upload File"
            multiple="false"
          />
          <div class="slds-text-body_small slds-text-color_error"
            >{!v.fileName}
          </div>
          <br />
        </div>
      </div>
    </div>
  </div>

  <aura:if isTrue="{!v.showMain}">
    <div
      class="slds-m-around--large"
      ondragover="{!c.onDragOver}"
      ondrop="{!c.onDrop}"
    >
      <div
        aura:id="holder"
        class="slds-m-top--medium slds-align--absolute-center"
        style="background-color:#bfbfb2; height:100px"
      >
        <h1>Drag and Drop CSV file here</h1>
      </div>
    </div>
    <aura:set attribute="else">
      <ui:outputRichText
        class="uiOutputRichText slds-m-around--large"
        value="{!v.TargetFileName}"
      />
      <ui:outputRichText
        class="uiOutputRichText slds-m--around-large"
        value="{!v.TableContent}"
      />
      <div class="slds-p-around--large slds-align--absolute-center">
        <lightning:button
          label="Save"
          variant="brand"
          onclick="{!c.processFileContent}"
        />
        <lightning:button
          label="Cancel"
          variant="brand"
          onclick="{!c.cancel}"
        />
      </div>
    </aura:set>
  </aura:if>

  <!--old-->
</aura:component>

Controller:

({
    
    onchange: function(component, event, helper) 
    {
     	event.stopPropagation();
        event.preventDefault();
     	//var files=event.dataTransfer.files;
        //helper.readFile(component,helper,files[0]);
        debugger;
        var fileName = 'No File Selected..';
        if (event.getSource().get("v.files").length > 0) { 
            fileName = event.getSource().get("v.files")[0];//['name'];
        }
        component.set("v.fileName", fileName['name']);
        helper.readFile(component,helper,fileName);
        
  	},
    
	onDragOver : function(component, event, helper) {
		event.preventDefault();
	},
    
    onDrop : function(component, event, helper) {
		event.stopPropagation();
        event.preventDefault();
        event.dataTransfer.dropEffect='copy'; 
        var files=event.dataTransfer.files;
        helper.readFile(component,helper,files[0]);
	},
    
    processFileContent : function(component,event,helper){
        helper.saveRecords(component,event);
    },
    
    cancel : function(component,event,helper){
        component.set("v.showMain",true);
    }
})

Helper:

({
    readFile: function(component, helper, file) {
        if (!file) return;
        console.log('file'+file.name);
        if(!file.name.match(/\.(csv||CSV)$/)){
            return alert('only support csv files');
        }else{
            
            reader = new FileReader();
            reader.onerror =function errorHandler(evt) {
                switch(evt.target.error.code) {
                    case evt.target.error.NOT_FOUND_ERR:
                        alert('File Not Found!');
                        break;
                    case evt.target.error.NOT_READABLE_ERR:
                        alert('File is not readable');
                        break;
                    case evt.target.error.ABORT_ERR:
                        break; // noop
                    default:
                        alert('An error occurred reading this file.');
                };
            }
            //reader.onprogress = updateProgress;
            reader.onabort = function(e) {
                alert('File read cancelled');
            };
            reader.onloadstart = function(e) { 
                
                var output = '<ui type=\"disc\"><li><strong>'+file.name +'</strong> ('+file.type+')- '+file.size+'bytes, last modified: '+file.lastModifiedDate.toLocaleDateString()+'</li></ui>';
                component.set("v.filename",file.name);
                component.set("v.TargetFileName",output);
               
            };
            reader.onload = function(e) {
                var data=e.target.result;
                component.set("v.fileContentData",data);
                console.log("file data"+JSON.stringify(data));
                var allTextLines = data.split(/\r\n|\n/);
                var dataRows=allTextLines.length-1;
                var headers = allTextLines[0].split(',');
                
                console.log("Rows length::"+dataRows);
               
              
                	var numOfRows=component.get("v.NumOfRecords");
                    if(dataRows > numOfRows+1 || dataRows == 1 || dataRows== 0){
                   
                     alert("File Rows between 1 to "+numOfRows+" .");
                    component.set("v.showMain",true);
                    
                } 
                else{
                    var lines = [];
                    var filecontentdata;
                    var content = "<table class=\"table slds-table slds-table--bordered slds-table--cell-buffer\">";
                    content += "<thead><tr class=\"slds-text-title--caps\">";
                    for(i=0;i<headers.length; i++){
                        content += '<th scope=\"col"\>'+headers[i]+'</th>';
                    }
                    content += "</tr></thead>";
                    for (var i=1; i<allTextLines.length; i++) {
                        filecontentdata = allTextLines[i].split(',');
                        if(filecontentdata[0]!=''){
                            content +="<tr>";
                            
                            for(var j=0;j<filecontentdata.length;j++){
                                content +='<td>'+filecontentdata[j]+'</td>';
                            }
                            content +="</tr>";
                        }
                    }
                    content += "</table>";
                    
                    component.set("v.TableContent",content);
					component.set("v.showMain",false);                   
                }
            }
            reader.readAsText(file);
            
        }
        var reader = new FileReader();
        reader.onloadend = function() {
         
        };
        reader.readAsDataURL(file);
    },
    
    saveRecords : function(component,event){
        var action = component.get("c.processData");
        //var fieldsList=['Name','Phone','AccountNumber']; //Please write your code dynamic fields
        debugger;
         var extraData = component.get("v.fileContentData");
        
        var allTextLines = extraData.split(/\r\n|\n/);
        var dataRows=allTextLines.length-1;
        var headers = allTextLines[0].split(',');
        var fieldsList = headers;
        debugger;
        action.setParams({ fileData : component.get("v.fileContentData"),
                          sobjectName:'Account', //Any object
                          fields:fieldsList});
        action.setCallback(this, function(response) {
            var state = response.getState();
            if (state === "SUCCESS") {
                component.set("v.showMain",true);
                alert('saved successfully');
            }
            else if (state === "INCOMPLETE") {
                // do something
            }
            else if (state === "ERROR") {
                var errors = response.getError();
                if (errors) {
                    if (errors[0] && errors[0].message) {
                        console.log("Error message: " + 
                                 errors[0].message);
                    }
                } else {
                    console.log("Unknown error");
                }
            }
        });
        $A.enqueueAction(action);
    }

});

Apex Controller:

public class csvController { 

    @AuraEnabled
    public static void processData(String fileData, 
                                   String sobjectName, 
                                   List<String> fields) 
    {
	 
        
       System.debug('fileData:::'+filedata);
       System.debug('sobjectName:::'+sobjectName);
       System.debug('fields:::'+fields);
       
        Account a = new Account();
        List<Account> accts = new List<Account>();
        
        List<sObject> myList = new List<sObject>();
        Schema.SObjectType targetType = Schema.getGlobalDescribe().get(sobjectName);
        try{
            if(fileData!=null) { 
                String[] fileLines = new String[]{};
               fileLines = fileData.split('\n');
                //for content
                
                for (Integer i=1,j=fileLines.size();i<j;i++){
                  String[] inputvalues = new String[]{};
                  inputvalues = fileLines[i].split(',');
                  sObject obj = targetType.newSObject();
                   integer rowsize=inputvalues.size();
                   //System.debug('rowsize::'+rowsize);
                   //System.debug('fields size'+fields.size());
                   for(integer l=0;l<rowsize-1;l++){
                       //system.debug('fields.get(l)'+fields.get(l)); 
                       if (fields.get(l) == 'name') { 
                           if(String.isNotBlank(inputvalues[l]) )
                           {
                              String value= inputvalues[l].length()>255 ? inputvalues[l].substring(0,254) : inputvalues[l];
                              obj.put(fields.get(l),value);
                              //system.debug('field name: ' + fields.get(l));
                              //system.debug('Field name Value ' + value);
                           }else{
                                obj.put(fields.get(l),'');
                           }
                       }
                   
                      
                   }
             //   System.debug('Obj::::'+obj);
                   myList.add(obj);

               }
                
                //
            }
            if (myList.size() > 0) { 
                System.debug('myList::::'+myList);
              insert myList;
        	}
        }catch(Exception e){
             System.debug('exception'+e);   
        }
       
    }
}

Output:

CSV File:

Name,Department,Manager,Salary
Robin Hood,,,200
Arsene Wenger,Bar,Friar Tuck,50
Friar Tuck,Foo,Robin Hood,100
Little John,Foo,Robin Hood,100
Sam Allardyce,,,250
Dimi Berbatov,Foo,Little John,50

Happy coding!

Leave a Reply

Your email address will not be published. Required fields are marked *