
Download Data as CSV File With JavaScript In Salesforce Lightning Component
Hi guys, Today In this post we are seeing that how to Download/Export Data as CSV File format With Client Side JavaScript controller In Salesforce Lightning Component.
What is the CSV File ?
CSV stands for “comma-separated values”. CSV is a simple file format used to store tabular data, like a spreadsheet or database. Its data fields are most often separated, by a comma. Files in the CSV format can be imported to and exported from programs that store data in tables, such as Microsoft Excel or OpenOffice etc.
Prerequisites : basic understanding of Lightning Component, JavaScript and Apex Programming.
In This Sample, we will create a simple Lightning Component which is showing the Contact [salesforce standard object] Records. and also creating a HTML Button to download table data as CSV format.
Output:
CSV File:
apex Controller [csvDownloadCtrl.apxc]
public class csvDownloadCtrl { @AuraEnabled public static list <contact> fetchContact(){ List <contact> returnConList = new List < contact > (); for(contact con: [SELECT firstName, LastName, Department, MobilePhone From contact LIMIT 1000]) { returnConList.add(con); } return returnConList; } }
- Above apex class is just return the List of Contact Records.
Lightning Component [csvSample.cmp]
<aura:component controller="csvDownloadCtrl"> <!--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="contact[]"/> <!--Use "slds-m-around- -xx-large" class to add standard Large padding to the component--> <div class="slds-m-around--xx-large"> <button class="slds-button slds-button--brand" onclick="{!c.downloadCsv}">Download As CSV</button> <br/><br/> <!--HTML tabel for display Contact Records--> <table class="slds-table slds-table--bordered slds-table--cell-buffer"> <thead> <tr class="slds-text-title--caps"> <th class="slds-is-sortable slds-text-title--caps" scope="col"> <span class="slds-truncate" title="Name">First Name</span> </th> <th class="slds-is-sortable slds-text-title--caps" scope="col"> <span class="slds-truncate" title="Last Name">Last Name</span> </th> <th class="slds-is-sortable slds-text-title--caps" scope="col"> <span class="slds-truncate" title="Department">Department</span> </th> <th scope="col"> <div class="slds-truncate" title="MobilePhone">Mobile Phone</div> </th> </tr> </thead> <!--table body start, Iterate contact list as a <tr> --> <tbody> <aura:iteration items="{!v.ListOfContact}" var="con"> <tr> <th scope="row"> <div class="slds-truncate" title="{!con.FirstName}">{!con.FirstName}</div> </th> <th scope="row"> <div class="slds-truncate" title="{!con.LastName}">{!con.LastName}</div> </th> <th scope="row"> <div class="slds-truncate" title="{!con.Department}">{!con.Department}</div> </th> <th scope="row"> <div class="slds-truncate" title="{!con.MobilePhone}">{!con.MobilePhone}</div> </th> </tr> </aura:iteration> </tbody> </table> </div> </aura:component>
- See Code Comments
JavaScript Controller [csvSampleController.js]
({ // ## 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 }, })
- See Code Comments
JavaScript Helper [csvSampleHelper.js]
({ 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 valirable store fields API Names as a key // this labels use in CSV file header keys = ['FirstName','LastName','Department','MobilePhone','Id' ]; 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; } csvStringResult += '"'+ objectRecords[i][skey]+'"'; counter++; } // inner for loop close csvStringResult += lineDivider; }// outer main for loop close // return the CSV formate String return csvStringResult; }, })
- See Code Comments
- If You want add another column to CSV file from object, add Field API name to Line number 33 on JS helper controller. such as -:
keys = ['FirstName','LastName','Department','MobilePhone','Id','CustomFieldApiName__c' ];
TestApp.app
<aura:application extends="force:slds"> <c:csvSample /> <!-- here c: is org. namespace prefix--> </aura:application>
After the winter 17 release you can use the Lightning Design System style in Lightning Apps by extends=”fore:slds”. The Salesforce Lightning Design System provides a look & feel that’s consistent with Lightning Experience. Use Lightning Design System styles to give your custom applications a UI that is consistent with Salesforce.
Some Useful Resources :
Use aura:valueInit [aura:handler name=”init”]..
https://www.lightningdesignsystem.com/components/data-tables/
Like our facebook page for new post updates. & Don’t forget to bookmark this site for your future reference. 🙂
if you have any suggestions or issue with it, you can post in comment box 🙂
75 comments
Hello, awesome site. But unable to register. Can you please check?
good explanation,
Is this component is working Dynamically if no what are the things we need to Implement.
Hi,
Thanks for the blog.
Can you please help me how to export data in multiple sheets inside one excel. I have three data tab to export inside one excel sheet.
Also when I am trying to export the lookup column like CreatedBy.LastName, its not giging any result.
Hi Rohith,
Did u got code for multiple sheets in one excel file ..
iF u have can u please send me code
[email protected]
Hi ,
I tried to download the data into csv using above code,but i am geeting “undefined” in the csv sheet.
Hi abhilash,
if you have got “undefined” it means you don’t have any data(null) value in record field.
if you don’t want get “undefined” in csv then add a undefined check in helper javaScript controller i.e
if(objectRecords[i][skey] != undefined){
csvStringResult += '"'+ objectRecords[i][skey]+'"';
}else{
csvStringResult += '"'+ '' +'"';
}
now if you have null value in record field it will be blank in csv instead Of undefined
thanks
Hi ,
Thanks for your reply . Is there any way to ignore the columns so that it should not come in csv file?
Hi Piyush,
I am not able to post comment in forum neither able to register.
I need help regarding export to excel. I refer your blog, but its working to export data in 1 sheet for workbook. I need to export data in two/three sheets of a single workbook. Like 1 sheet will contains open cases, 2nd sheet will contain closed cases etc. Request you to please help, if possible.
Hi..
i am getting error when i click on “Download as Csv” button though data is populated.
Here is the error..
This page has an error. You might just need to refresh it. Action failed: Ashi:csvSample$controller$downloadCsv [Access is denied. ] Failing descriptor: {Ashi:csvSample$controller$downloadCsv}
Can u please help me on this?
Regards,
Sudheer.
Hi Sudheer,
I Guess you are using a custom namespace in your org,
you have need to update your code with custom namespace code standards :
please reference below doc.
https://developer.salesforce.com/docs/atlas.en-us.lightning.meta/lightning/namespace_using_reference.htm#namespace_using_reference
Hi ,
Instead of showing the API names in csv sheet , can we display the Field label in the sheet?
yes, you can do it by change on Line Number 36 in javaScript Helper
Use below line :
csvStringResult += [‘User First Name’,’User Last Name’,’My Department’,’Custom Phone’,’Object Id’ ];
insteadOf : csvStringResult += keys.join(columnDivider);
Thanks
This is working fine normally. However, in my scenario, I am using an inline vf page on account detail page. In this inline VF page, there is lightning component which has “download as CSV” button. When I click on this button it says “We’d like to open the Salesforce page null… in a new tab. Because of your browser settings, we need your permission first.” in lightning experience. However, it works fine in classic. Any help would be much appreciated.
Thanks
Do you get any work around for this issue , I am facing same issue in lightning ?
Hi,
Is there any way we can make Download file Name dynamic.
this part hiddenElement.download = ‘ExportData.csv’;
with some present date stamp etc
Thanks
Hi ,
In hiddenElement.download = ‘ExportData.csv’;
Can we give dynamic name with datetime stamp including?
How to parse a CSV file in lightning
Hi,
Thank you for the post. It is working fine for me. But I’m looking to fetch related fields as well. For example, I added custom field abc__r.xyz.__c in apex controller. But the value in csv is showing as undefined for all related fields.
Now in the helper, for the keys, im using the same api name such as abc__r.xyz.__c.
keys = [‘abc__r.xyz.__c‘,‘FirstName’,‘LastName’,‘Department’,‘MobilePhone’,‘Id’ ];
Do I need to follow different approach to retrieve related fields.
Thank you.
Hi,
Thank you for the post. It is working fine for me. But I also want to fetch related fields in the soql. For example I need custom field abc__r.xyz__c. Added it in soql.
Now in the helper, I added api name in the same format abc__r.xyz__c.
I added it in keys variable as below.
keys = [‘abc__r.xyz__c‘,’FirstName’,’LastName’,’Department’,’MobilePhone’,’Id’ ];
But the values in the csv are showing as ‘undefined’. Do I need to follow a different approach to get related fields.
Thank you.
I’m facing the same issue as yours, I am querying related fields and I’m getting them as undefined even though I have values in the fields. Please let me know if you have a workaround for this.
Hello,
I’m facing the same issue, all my rows, and columns are “undifined”…
Does everybody know how can it be fixed?
regards
U sure u’re not missing a ; or a { bro ?
duno homie, the thang ain’t work
Hi Rakesh,
Did you find a solution for this?
Thanks
Praveen
Hi Rakesh,
Did you find a solution for this? If Yes, please can you share with us. I am also facing the same issue.
Thanks
Praveen
Hi.. I am not able to download CSV on first click. its getting downloaded on second click only.
Can u pls help me on this
Try to add a default value to listOfContact:
Hi, I’m able to download the CSV file but there’s a special character appearing when it was downloaded. Can u please help me with this
what kind of special characters ?
Did you resolve this?
Does anyone have found out a way to fixe the “undifined” values in the document?
regards
if you have got “undefined” it means you don’t have any data(null) value in record field.
if you don’t want get “undefined” in csv then add a undefined check in helper javaScript controller i.e
if(objectRecords[i][skey] != undefined){
csvStringResult += '"'+ objectRecords[i][skey]+'"';
}else{
csvStringResult += '"'+ '' +'"';
}
now if you have null value in record field it will be blank in csv instead Of undefined
thanks
The problem is that i DO have data but the result is still undifined. Any clue?
i am facing the same issue please somebody help for this.
post your issue on developer forums and share question URL here, so i can look into your issue. Thanks
https://developer.salesforce.com/forums
sfdcmonkey: If we want to use/modify/copy your code, is that OK? No licenses or notices that we need to be aware of?
Hi Christian, yes you can, it’s all open source. enjoy
Hi,
Thanks for the blog. It helped me a lot. I have strucked in the mid i have writen a SOQL query with the relationship for eg:- abc__r.xyz__c, i cannot able to get the values while exporting into csv. I have used in the Key[‘abc__r.xyz__c’] but its not working. Please anyone can suggest a solution for this?
first query abc__r.xyz__c in your apex class SOQL query.
and in your lightning component add new row in aura:iteration tag :
and in your javaScript helper function on line number 33 add your related field,such as:
keys = ['FirstName','LastName','Department','Level__c','MobilePhone','Id','abc__r' ];
Update line number 50 with below statement :
if(typeof objectRecords[i][skey] === 'object'){
csvStringResult += '"'+ objectRecords[i][skey].xyz__c+'"';
}else{
csvStringResult += '"'+ objectRecords[i][skey]+'"';
}
This will be solve your issue
Thanks
Hi Piyush,
I need to download only selected records with the check box next to each records by clicking on Download Button. pls help with me download code or logic if possible.
kindly post your query and code here :
https://developer.salesforce.com/forums
Thanks
Hi
I am getting value abc__r.xyz__c in excel but in column header i am getting abc__r.
Please help.
omg, in the words of don jr (but not with his nefarious purpose), I LOVE IT. thanks!
Thanks for your feedback @Gus
Thanks for the code. Is that possible to download the csv if we have paginated the records? What do we need to do in that case? Please clarify. Thanks
Hi. This is really useful. I have Custom Label as Excel Columns and it doesnt display translated labels correctly in in the CSV file.
Hi ,
Great blog. can you please also help me on how to upload the excel using lighting and parse it to perform DML operations on excel records. Through VF I know but in lighting ,facing the issue to pass the file from lighting to apex.
Thanks in advance 🙂
HI Piyush.. loved the code thanks so much !!
do we have a similar code for downloading data as XLS file. M not able to find it anywhere
HI Piyush .. loved the code thank so much!
Do we have a similar code for downloading data as xls file as well? m not able to find it anywhere
Hi ,
Thanks for sharing this. It was very helpful.
Can you please also tell me that how can I get the size of the CSV file and show the indicator of the downloading file that how much size is downloaded.
How can we download the data into multiple sheets in lightning?
Hi,
I have a visualforce tab. I am using lightning component to download csv file. this lightning component has been used in visualforce page. VF tab the download button is working fine in salesforce classic and tried the same thing in lightning I am getting an error “Page doesn’t exist”. Please help me if you have faced the same issue.
Thanks in advance
“
Hi Piyush,
This is nice post regarding csv download and helpful also but i have a query that if i want to get the lookup field how t pass it on keys. As i am unable to get the parentfield value on export.
example Account.Name
Piyush, you can use a wrapper class to populate all the required fields on the apex controller and pass that to the js controller.
This code doesn’t seem to work in IE. Any alternative JS snippet to get this working in IE?
Hi,
I am using lightning component to download csv file and successfully worked, but I want header row should in bold.How can I achieve that.If this possible or not ?
When i click on the button on chrome, the page will freeze until the process is finished, is this a browser setting issue or can we do something to prevent this? (firefox works fine)
I want to fill each row or column with color
Hello ,
Thanks. This helped me .Actually I need to export large data around 20K records and it is giving me ‘network error’ when I click on download button for csv download.please advise what can we do in this scenario
hello,
Thanks. It works fine. I have columns highlighted with some colours based on some conditions and date format these are not coming in the csv. how to get them?.
Hello,
I am getting an error as access denied with edge browser. Can you help me with that.
Hey,
This is giving me access is denied in edge browser. I checked all the lines and found that it’s triggering on hiddenelement.click().
Can you please help me out there
Hi,
I was able to get only 34 lines, Please help me to get all the data
Hi,
This code is not working when any field contains special character.Please help me
Thank You,
Satya
HI,
We are unable to get special characters data, data has stopped in csv where special character exists. Please help me with getting special characters data also.
Thank You,
Mani
Try encodeuriComponent instead of encodeURI
Hi,
The download works fine.But the field value in other language EG: contact Name is ??????it
it is corrupted in the downloaded csv file .Can we avoid this programatically
How to make autofit column in above code.
How to add autofit column in above code?
Their is problem with code it doesn’t work well with permission set assignment or refrenced fields it always shows undefined in our case.
Hello Sfdc monkey,
Nice explanation for download functionality what about if we have multiple related fields like abc_c.xyz_r.mnp_r.
How we can fetch this value please help.
Thanks
PB
My apologies if this is a dumb question, but I’ve used the code above to create this for my custom object, but am not sure how it is supposed to be implemented. I thought it may be a component on the Lightning Page, but it doesn’t show up. I tried to create a custom action, but again it was not available.
How do I add this component to be used?
if any field values # character , the download report not showing the values after#.
when running report all the rows displaying ,but # value not working in download
Upto 1000 records it is working fine..if we increase the limit to 5k records…I am getting unresponsive page error…