How to Read CSV File using Lightning Component?

How to Read CSV File using Lightning Component?
How to Read CSV File using Lightning Component

Hello Salesforce Wizards !!

Previously, I have told you http://forceblogs.com/alertbox-alert-your-users-in-salesforce-dynamically/ . Today in this post, I am going to share the information about how to read CSV and generate JSON data using the lightning component.

Well, why I am sharing this because I have been working on kind of similar task and I face a lot of challenges, So thought to share with all.

Now, here we begin with the code how can you read the CSV file, I am using Javascript FileReader API. The FileReader Object reads the content of the files, using file or Blob object we are inserting this file into a custom object to store the file.

Note: Please download the static resource file from here .

Then, you need to create a lightning component and handle the import event.

Notice that we have implemented lightning:input interface on ExcelImport so that we can handle CSV table files.

ExcelImport.cmp

<ltng:require scripts="{!$Resource.ExcelImport}"/>
<aura:registerEvent name="onImport" type="c:ExcelImportEvent"/>

<aura:attribute name="label" type="String" description="Label for input" default="Import Excel File" required="false"/>
<aura:attribute name="class" type="String" description="Additional styles" required="false"/>
<aura:attribute name="variant" type="String" description="Input variant" required="false" default="standard"/>
<aura:attribute name="required" type="Boolean" description="Shows if input is mandatory" default="false"/>
<aura:attribute name="disabled" type="Boolean" description="Displays input disabled" default="false"/>
<!--<aura:attribute name="accept" type="String" default=".xls, .xlsx"/>-->
<aura:attribute name="accept" type="String" default=".csv, .xls, .xlsx"/>

<aura:attribute name="stretchedDropzone" type="Boolean" description="Makes dropzone stretchable" default="false"/>
<aura:attribute name="isLoading" type="Boolean" default="false" access="private"/>

<aura:attribute name="fileSizeThreshold" type="Integer" description="Max file size in bytes, default 10mb" default="10000000" required="false"/>
<aura:attribute name="messageFileSizeExceeded" type="String" default="File size exceeded" required="false"/>
<aura:attribute name="messageNoFileSpecified" type="String" default="No file specified" required="false"/>

<lightning:input type="file"
                 label="{!v.label}"
                 class="{!v.class
                    + (v.stretchedDropzone ? ' bigger-drop-zone' : '')
                    + (v.isLoading ? ' drop-zone-loading' : '')}"
                 variant="{!v.variant}"
                 required="{!v.required}"
                 disabled="{!v.disabled}"
                 onchange="{!c.onTableImport}"
                 multiple="false"
                 accept="{!v.accept}"/>

ExcelImportController.js

  ({
onTableImport: function (cmp, evt, helper) {
helper.disableExcelInput(cmp);
helper.importTableAndThrowEvent(cmp, evt, helper);
}
})

ExcelImportHelper.js

({
     disableExcelInput: function(cmp) {
         cmp.set("v.disabled", true);
         cmp.set("v.isLoading", true);
     },
enableExcelInput: function(cmp) {
    cmp.set("v.disabled", false);
    cmp.set("v.isLoading", false);
},

importTableAndThrowEvent: function(cmp, evt, helper) {
    evt.stopPropagation();
    evt.preventDefault();
    try {
        const file = helper.validateFile(cmp, evt);
        helper.readExcelFile(file)
        .then($A.getCallback(excelFile => {
            // console.log(JSON.stringify(excelFile));
            helper.throwSuccessEvent(cmp, excelFile);
        }))
            .catch($A.getCallback(exceptionMessage => {

            helper.throwExceptionEvent(cmp, exceptionMessage);

        }))
            .finally($A.getCallback(() => {
            helper.enableExcelInput(cmp);
        }))
        } catch (exceptionMessage) {
            console.log(exceptionMessage);
            helper.throwExceptionEvent(cmp, exceptionMessage);
            helper.enableExcelInput(cmp);
        }
        },

            validateFile: function(cmp, evt) {
                const files = evt.getSource().get("v.files");
                if (!files || files.length === 0 || $A.util.isUndefinedOrNull(files[0])) {
                    throw cmp.get("v.messageNoFileSpecified");
                }

                const file = files[0];
                const fileSizeThreshold = cmp.get("v.fileSizeThreshold");
                if (file.size > fileSizeThreshold) {
                    throw (cmp.get("v.messageFileSizeExceeded") + ': ' + fileSizeThreshold + 'b');
                }
                return file;
            },

            readExcelFile: function(file) {
                return new Promise(function (resolve, reject) {
                    var selectedFile =file;
                    let filename;
                    var reader = new FileReader();
                    reader.onload = function(event) {
                        filename = file.name;
                        var XL_row_object ;
                        var data = event.target.result;
                        var workbook = XLSX.read(data, {
                            type: 'binary'
                        });
                        // console.log(workbook.SheetNames.length);
                        workbook.SheetNames.forEach(function(sheetName) {
                            if(XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]).length!=0){
                                XL_row_object = XLSX.utils.sheet_to_row_object_array(workbook.Sheets[sheetName]);
                                //console.log(JSON.stringify(XL_row_object));
                                //document.getElementById("jsonObject").innerHTML = json_object;
                            }


                        })
                        try {
                            resolve({
                                "fileName": filename,
                                "xlsx":XL_row_object
                            });

                        } 
                        catch (error) {
                            reject(error);
                        }
                    };
                    reader.onerror = function(event) {
                        console.error("File could not be read! Code " + event.target.error.code);
                    };
                    reader.readAsBinaryString(selectedFile);
                });
            },

            throwExceptionEvent: function(component, message) {
                const errorEvent = component.getEvent("onImport");
                errorEvent.setParams({
                    "type": "ERROR",
                    "message": message
                });
                errorEvent.fire();
            },

            throwSuccessEvent: function(component, parsedFile) {
                const successEvent = component.getEvent("onImport");
                //console.log(JSON.stringify(parsedFile));
                successEvent.setParams({
                    "type": "SUCCESS",
                    "fileName": parsedFile.fileName,
                    "table": parsedFile.xlsx
                });
                successEvent.fire();
            }
        })

Now, Finally the Event :

<aura:event type="COMPONENT" description="ExcelImportEvent">
    <aura:attribute type="String" name="type" description="Type of the event: SUCCESS, ERROR" required="true"/>
    <aura:attribute type="String" name="message" description="Message" required="false"/>
    <aura:attribute type="String" name="fileName" description="File name" required="false"/>
    <aura:attribute type="Object" name="table" description="Parsed Excel table" required="false"/>
    <aura:attribute type="String" name="selectedFile" description="File" required="false"/>
    
</aura:event>

Let us know in the comment section if you find it useful!

If you have any issue, or you want to extend or add any point further Chat with us, We will be more than happy to assist you.

Support: For any kind of further Salesforce support, Chat with us we will be happy to assist you.

Popular Post:

Parul Singh

I’m a Salesforce Certified Service Cloud Consultant, Certified Administrator & Certified Platform Developer. I have 2 years of experience, currently working on Field Service Lightning, Lightning Flows and Learning Lightning Web Component. I was featured in the top Salesforce Bloggers of 2018 by www.forcetalks.com

You may also like...