Showing posts with label export data as csv file. Show all posts
Showing posts with label export data as csv file. Show all posts

Thursday, May 30, 2019

Export data as CSV File with javascript in salesforce Lightning Web Component(lwc)

This post explains how to export data table data as a CSV file using javascript in salesforce Lightning web component(lwc).

I created a simple Lighting web component, this component is displayed Account data and one button to download CSV file.

Example:
exportDataToCSVInLWC.html
<template>
    <lightning-card title="Export Data as CSV in Lightning Web Components" icon-name="custom:custom63">
        <template if:true={data}>
            <div class="slds-p-around_medium lgc-bg-inverse">
                <p>Do you want download data as a CSV format, Click Here &nbsp;
                    <lightning-button icon-name="utility:download" 
                                      label="Download as CSV" 
                                      title="Download CSV File"
                                      onclick={downloadCSVFile} variant="brand"></lightning-button>
                </p>
            </div>
            <div class="slds-m-around_medium">
                <!-- Datatable component -->
                    <lightning-datatable columns={columns} 
                                         data={data} 
                                         hide-checkbox-column="true"
                                         key-field="id"></lightning-datatable>
            
            </div>
        </template>
    </lightning-card>
</template>

exportDataToCSVInLWC.js
import { LightningElement, track} from 'lwc';
// importing accounts
import getAccountList from '@salesforce/apex/LWCExampleController.getAccounts';
// imported to show toast messages
import {ShowToastEvent} from 'lightning/platformShowToastEvent';


// datatable columns
const cols = [
    {label: 'Name',fieldName: 'Name'}, 
    {label: 'Industry',fieldName: 'Industry'},
    {label: 'Type',fieldName: 'Type'}, 
    {label: 'Phone',fieldName: 'Phone',type: 'phone'}, 
    {label: 'Rating',fieldName: 'Rating'}, 
    {label: 'Account Number',fieldName: 'AccountNumber'}, 
];

export default class ExportDataToCSVInLWC extends LightningElement {
    @track error;
    @track data;
    @track columns = cols;

    // this constructor invoke when component is created.
    // once component is created it will fetch the accounts
    constructor() {
        super();
        this.getallaccounts();
    }

    // fetching accounts from server
    getallaccounts() {
        getAccountList()
        .then(result => {
            this.data = result;
            this.error = undefined;
        })
        .catch(error => {
            this.error = error;
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error while getting Accounts', 
                    message: error.message, 
                    variant: 'error'
                }),
            );
            this.data = undefined;
        });
    }

    // this method validates the data and creates the csv file to download
    downloadCSVFile() {   
        let rowEnd = '\n';
        let csvString = '';
        // this set elminates the duplicates if have any duplicate keys
        let rowData = new Set();

        // getting keys from data
        this.data.forEach(function (record) {
            Object.keys(record).forEach(function (key) {
                rowData.add(key);
            });
        });

        // Array.from() method returns an Array object from any object with a length property or an iterable object.
        rowData = Array.from(rowData);
        
        // splitting using ','
        csvString += rowData.join(',');
        csvString += rowEnd;

        // main for loop to get the data based on key value
        for(let i=0; i < this.data.length; i++){
            let colValue = 0;

            // validating keys in data
            for(let key in rowData) {
                if(rowData.hasOwnProperty(key)) {
                    // Key value 
                    // Ex: Id, Name
                    let rowKey = rowData[key];
                    // add , after every value except the first.
                    if(colValue > 0){
                        csvString += ',';
                    }
                    // If the column is undefined, it as blank in the CSV file.
                    let value = this.data[i][rowKey] === undefined ? '' : this.data[i][rowKey];
                    csvString += '"'+ value +'"';
                    colValue++;
                }
            }
            csvString += rowEnd;
        }

        // Creating anchor element to download
        let downloadElement = document.createElement('a');

        // This  encodeURI encodes special characters, except: , / ? : @ & = + $ # (Use encodeURIComponent() to encode these characters).
        downloadElement.href = 'data:text/csv;charset=utf-8,' + encodeURI(csvString);
        downloadElement.target = '_self';
        // CSV File Name
        downloadElement.download = 'Account Data.csv';
        // below statement is required if you are using firefox browser
        document.body.appendChild(downloadElement);
        // click() Javascript function to download CSV file
        downloadElement.click(); 
    }

}

exportDataToCSVInLWC.js-meta.xml
<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata" fqn="exportDataToCSVInLWC">
    <apiVersion>45.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__AppPage</target>
        <target>lightning__RecordPage</target>
        <target>lightning__HomePage</target>
    </targets>
</LightningComponentBundle>

Apex Class
public inherited sharing class LWCExampleController {
    
    @AuraEnabled(Cacheable = true)
    public static List<Account> getAccounts(){
      return [SELECT Id, Name,Industry, Type, Phone, Rating, AccountNumber FROM Account ORDER BY Name LIMIT 10];
    }
}

Result: