Import & Export data from CSV file using Lightning Component

By | December 9, 2019

Hi guys, here am going to show you, how to import the data and export the data from csv file using lightning component.

Apex Controller

public class csvImportExport {
   /* for import data into sobject and insert data from csv file  */ 
    @AuraEnabled
    public static string insertData(String strfromle){
        String returnresponse ='';
        List<Account> AccoutnListtoInsert = new List<Account>();
        //system.debug('strfromle = ' + strfromle);
        List<fieldWrapper> datalist = (List<fieldWrapper>)JSON.deserialize(strfromle, List<fieldWrapper>.class);
        //system.debug('datalist = ' + datalist);
        //system.debug('datalistSize = ' + datalist.size());
        for(fieldWrapper wrapper: datalist){
            Account acc =new  Account();
            acc.Name = wrapper.Name;
            acc.Phone = wrapper.phone;
            acc.AccountNumber = wrapper.AccountNumber;
            AccoutnListtoInsert.add(acc);            
        }
        
        if(AccoutnListtoInsert.size() > 0){
            try {
                insert AccoutnListtoInsert;
                returnresponse = 'SUCCESS';
            }
            catch(Exception ex){
                returnresponse = 'ERROR';
            }
        }
        return returnresponse;
    }
    
    public class fieldWrapper{        
        public String Name;        
        public String AccountNumber;        
        public String phone;
        
    } 
    
    /* for export data into csv file  */
    @AuraEnabled
    public static list <Account> fetchContact(){      
        List <Account> returnConList = new List < Account > ();        
        for(Account con: [SELECT Name, phone, AccountNumber From Account ]) {
            returnConList.add(con);
        }
        return returnConList;
    }
    
}

Lightning Component

<aura:component controller="csvImportExport">          
    <!-- export attributes start  -->
    <!--aura init handler, call js "loadContactList" function on component load, and display contact data on table-->   
    <aura:handler name="init" value="{!this}" action="{!c.loadContactList}"/>
    
    <!--Declare Attribute for store Contact Records List-->  
    <aura:attribute name="ListOfContact" type="Account[]"/> 
    <!-- export attributes end-->
    
    <!-- Import attributes start  -->
    <aura:attribute name="ShowModule" type="boolean" default="false"/>
    <aura:attribute name="showcard" type="boolean" default="false"/>
    <!-- Import attributes end  -->
    
    <div>
        <input type="file" class="file" aura:id="file" onchange="{!c.showfiledata}"/>
        <lightning:button label="Create Accounts" onclick="{!c.CreateRecord}" class="slds-button slds-button--brand"/>
        <lightning:button label="Download Account As CSV" onclick="{!c.downloadCsv}" class="slds-button slds-button--brand"/>        
    </div>
    
    <aura:if isTrue = "{!v.showcard}">
        <lightning:card>
            <div id="divCSV">
            </div>  
        </lightning:card>
    </aura:if>
</aura:component>

Controller js

({    
    CreateRecord: function (component, event, helper) {
        var fileInput = component.find("file").getElement();
        var file = fileInput.files[0];
        //alert(file);
        if (file){
            //console.log("File");
            var reader = new FileReader();
            reader.readAsText(file, "UTF-8");
            reader.onload = function (evt) {
                
                //console.log("EVT FN");
                var csv = evt.target.result;
                //console.log('csv file contains'+ csv);
                var result = helper.CSV2JSON(component,csv);
                //console.log('result = ' + result);
                //console.log('Result = '+JSON.parse(result));
                helper.CreateAccount(component,result);
                
            }
            reader.onerror = function (evt) {
                //console.log("error reading file");
            }
        }
        
    },
    
    showfiledata :  function (component, event, helper){        
        var fileInput = component.find("file").getElement();
        var file = fileInput.files[0];
        if (file) {
            component.set("v.showcard", true);
            //console.log("File");
            var reader = new FileReader();
            reader.readAsText(file, "UTF-8");
            reader.onload = function (evt) {
                var csv = evt.target.result;
                var table = document.createElement("table");
                var rows = csv.split("\n");
                for (var i = 0; i < rows.length; i++) {
                    var cells = rows[i].split(",");
                    if (cells.length > 1) {
                        var row = table.insertRow(-1);
                        for (var j = 0; j < cells.length; j++) {
                            var cell = row.insertCell(-1);
                            cell.innerHTML = cells[j];
                        }
                    }
                }
                var divCSV = document.getElementById("divCSV");
                divCSV.innerHTML = "";
                divCSV.appendChild(table);
            }
            reader.onerror = function (evt) {
                //console.log("error reading file");
            }
        }
    },    
    
    // export data start from here    
    // ## function call on component load  
    loadContactList: function(component, event, helper){
        helper.onLoad(component, event);
    },
    
    // ## function call on Click on the "Download As CSV" Button. 
    downloadCsv : function(component,event,helper){
        
        // get the Records [contact] list from 'ListOfContact' attribute 
        var stockData = component.get("v.ListOfContact");
        
        // call the helper function which "return" the CSV data as a String   
        var csv = helper.convertArrayOfObjectsToCSV(component,stockData);   
        if (csv == null){return;} 
        
        // ####--code for create a temp. <a> html tag [link tag] for download the CSV file--####     
        var hiddenElement = document.createElement('a');
        hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
        hiddenElement.target = '_self'; // 
        hiddenElement.download = 'ExportData.csv';  // CSV file Name* you can change it.[only name not .csv] 
        document.body.appendChild(hiddenElement); // Required for FireFox browser
        hiddenElement.click(); // using click() js function to download csv file
    }, 
})

Helper Js

({
    CSV2JSON: function (component,csv) {
        //  console.log('Incoming csv = ' + csv);
        
        //var array = [];
        var arr = []; 
        
        arr =  csv.split('\n');
        //console.log('Array  = '+array);
        // console.log('arr = '+arr);
        arr.pop();
        var jsonObj = [];
        var headers = arr[0].split(',');
        for(var i = 1; i < arr.length; i++) {
            var data = arr[i].split(',');
            var obj = {};
            for(var j = 0; j < data.length; j++) {
                obj[headers[j].trim()] = data[j].trim();
                //console.log('obj headers = ' + obj[headers[j].trim()]);
            }
            jsonObj.push(obj);
        }
        var json = JSON.stringify(jsonObj);
        //console.log('json = '+ json);
        return json;
        
        
    },
    
    CreateAccount : function (component,jsonstr){
        // console.log('jsonstr' + jsonstr);
        var action = component.get('c.insertData');
        //  alert('Server Action' + action);    
        action.setParams({
            strfromle : jsonstr
        });
        action.setCallback(this, function(response) {
            var state = response.getState();
            //alert(state);
            if (state === "SUCCESS") {  
                var result=response.getReturnValue();
                alert("Accounts Inserted Succesfully");
                
            }
            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");
                    //alert('Unknown');
                }
            }
        }); 
        
        $A.enqueueAction(action);    
        
    },
    
    
    //export helper start from here
    onLoad: function(component, event) {
        //call apex class method
        var action = component.get('c.fetchContact');
        action.setCallback(this, function(response){
            //store state of response
            var state = response.getState();
            if (state === "SUCCESS") {
                //set response value in ListOfContact attribute on component.
                component.set('v.ListOfContact', response.getReturnValue());
            }
        });
        $A.enqueueAction(action);
    },
    
    convertArrayOfObjectsToCSV : function(component,objectRecords){
        // declare variables
        var csvStringResult, counter, keys, columnDivider, lineDivider;
        
        // check if "objectRecords" parameter is null, then return from function
        if (objectRecords == null || !objectRecords.length) {
            return null;
        }
        // store ,[comma] in columnDivider variabel for sparate CSV values and 
        // for start next line use '\n' [new line] in lineDivider varaible  
        columnDivider = ',';
        lineDivider =  '\n';
        
        // in the keys variable store fields API Names as a key 
        // this labels use in CSV file header  
        keys = ['Name','Phone','AccountNumber' ];
        
        csvStringResult = '';
        csvStringResult += keys.join(columnDivider);
        csvStringResult += lineDivider;
        
        for(var i=0; i < objectRecords.length; i++){   
            counter = 0;            
            for(var sTempkey in keys) {
                var skey = keys[sTempkey]; 
                
                // add , [comma] after every String value,. [except first]
                if(counter > 0){ 
                    csvStringResult += columnDivider; 
                } 
                // if condition for blank column display if value is empty
                if(objectRecords[i][skey] != undefined){
                    csvStringResult += '"'+ objectRecords[i][skey]+'"'; 
                }else{
                    csvStringResult += '"'+ '' +'"';
                }
                counter++;
                
                
            } // inner for loop close 
            csvStringResult += lineDivider;
        }// outer main for loop close 
        
        // return the CSV formate String 
        return csvStringResult; 
        
    },
})

Application

<aura:application extends="force:slds">
    <c:csvImportExport />
</aura:application>

Output

Choose file and click on create Account button. then data will be inserted.
It will support only for csv file.
Download button is for downloading Account data, give the required fields in Apex to download required data.

2 thoughts on “Import & Export data from CSV file using Lightning Component

  1. eric

    Thank you for share. I want to know the code for “choose file”.

  2. Vikky Singh

    This code becomes fail when we are uploading a large csv i.e. more than 15 MB. Can you please suggest how we can overcome this problem

Leave a Reply

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