0

I have a Lightning Component that renders data in a table. I currently have the logic that downloads as a CSV file. For some users,Excel is not auto formatting the file to display as Columns. So they want the file to be downloaded as an Xls or Xlsx file. I have done some research to see if there is a solution for downloading as an excel file on the client side itself but I couldn't find any. The logic that I currently have is below :

csvSample.cmp

<aura:component controller="csvDownloadCtrl">          

    <aura:handler name="init" value="{!this}" action="{!c.loadContactList}"/> 

    <aura:attribute name="ListOfContact" type="contact[]"/> 


  <div class="slds-m-around--xx-large">   
    <button class="slds-button slds-button--brand" onclick="{!c.downloadCsv}">Download As CSV</button> <br/><br/>

<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>

csvSampleController.js:

({
    loadContactList: function(component, event, helper){
       helper.onLoad(component, event);
    },

    downloadCsv : function(component,event,helper){

        var stockData = component.get("v.ListOfContact");

        var csv = helper.convertArrayOfObjectsToCSV(component,stockData);   
         if (csv == null){return;} 

         var hiddenElement = document.createElement('a');
          hiddenElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csv);
          hiddenElement.target = '_self';  
          hiddenElement.download = 'ExportData.csv';  
          document.body.appendChild(hiddenElement);
          hiddenElement.click(); 
        }, 
 })

csvSampleHelper.js:

({
   onLoad: function(component, event) {
      var action = component.get('c.fetchContact');
      action.setCallback(this, function(response){
         var state = response.getState();
         if (state === "SUCCESS") {
            component.set('v.ListOfContact', response.getReturnValue());
         }
      });
      $A.enqueueAction(action);
   },

   convertArrayOfObjectsToCSV : function(component,objectRecords){
        var csvStringResult, counter, keys, columnDivider, lineDivider;


        if (objectRecords == null || !objectRecords.length) {
            return null;
         }

        columnDivider = ',';
        lineDivider =  '\n';

        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] ;  

                  if(counter > 0){ 
                      csvStringResult += columnDivider; 
                   }   

               csvStringResult += '"'+ objectRecords[i][skey]+'"'; 

               counter++;

            } 
             csvStringResult += lineDivider;
          } 

        return csvStringResult;        
    },
})

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;
   }
}

PS : The data that is being downloaded is a list of Wrapper object. For keeping things simple I have added the Apex controller to return list of contacts. Also the use can filter the data on the component, So I have to download the data that is available on the Component after filtering.

Any help is greatly appreciated. Thanks

0

Can you try salesforce standard report solution and try export it : https://help.salesforce.com/articleView?id=reports_export.htm&type=5

| improve this answer | |

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.