Download Salesforce Record in Excel Format using Lightning Web Component

Download Salesforce Record in Excel Format using Lightning Web Component

SheetJS Library can be used in the Salesforce Lightning Web Component to download the record in the Excel format.

1. Go to https://cdn.sheetjs.com/.

2. Select xlsx.full.min.js from the current version. Right click and use Save As option to save the JavaScript as a .js file.

3. The downloaded SheetJS Library JavaScript file should be stored in the Static Resource to reference in the Lightning Web Component.

Sample Lightning Web Component:

HTML:

<template>    
</template>

JavaScript:

import { 
    LightningElement, 
    api, 
    wire 
} from 'lwc';
import SheetJS from '@salesforce/resourceUrl/SheetJSLibrary'; 
import { loadScript } from 'lightning/platformResourceLoader';
import { getRecord } from 'lightning/uiRecordApi';
import { getRelatedListRecords } from 'lightning/uiRelatedListApi';
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

const ACCOUNT_FIELDS = [ 
    'Account.Name', 
    'Account.Industry', 
    'Account.AnnualRevenue' 
];
const CONTACT_FIELDS = [ 
    'Contact.Id', 
    'Contact.Name', 
    'Contact.Email' 
];

export default class ExportToExcel extends LightningElement {

    @api recordId;
    accountName;
    accountIndustry
    accountAnnualRevenue;
    contactRecords;

    @wire( getRecord, { 
        recordId: '$recordId', 
        fields: ACCOUNT_FIELDS } 
    )
    wiredRecord( { 
        error, data  } 
    ) {

        if ( error ) {

            let message = 'Unknown error';
            if ( Array.isArray( error.body ) ) {

                message = error.body.map( e => e.message ).join( ', ' );

            } else if ( typeof error.body.message === 'string' ) {

                message = error.body.message;

            }
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error while fetching Account information',
                    message,
                    variant: 'error',
                }),
            );

        } else if ( data ) {
            
            console.log( 
                'Account is',
                JSON.stringify( data ) 
            );
            this.accountName = data.fields.Name.value;
            this.accountIndustry = data.fields.Industry.value;
            this.accountAnnualRevenue = data.fields.AnnualRevenue.value;

        }
    }

    @wire( 
        getRelatedListRecords, {
        parentRecordId: '$recordId',
        relatedListId: 'Contacts',
        fields: CONTACT_FIELDS
    } )listInfo( { error, data } ) {

        if ( data ) {

            console.log( 
                'Data is', 
                JSON.stringify( data ) 
            );
            let tempRecords = [];

            data.records.forEach( obj => {

                let tempRecord = {};
                tempRecord.Id = obj.fields.Id.value;
                tempRecord.Name = obj.fields.Name.value;
                tempRecord.Email = obj.fields.Email.value;
                tempRecords.push( tempRecord );

            } );

            this.contactRecords = tempRecords;
            console.log( 
                'Records are',
                JSON.stringify( this.contactRecords ) 
            );
            
        } else if ( error ) {
            
            let message = 'Unknown error';
            if ( Array.isArray( error.body ) ) {

                message = error.body.map( e => e.message ).join( ', ' );

            } else if ( typeof error.body.message === 'string' ) {

                message = error.body.message;

            }
            this.dispatchEvent(
                new ShowToastEvent({
                    title: 'Error while fetching Account information',
                    message,
                    variant: 'error',
                }),
            );

        }
    }

    @api async invoke() {
        
        console.log( 'Inside invoke' );
        await loadScript(this, SheetJS); 

        const filename = 'Account - ' + 
            new Date().toLocaleDateString() + 
            '.xlsx';
        const workbook = XLSX.utils.book_new();
        const accountWorksheetData = [];
        const contactWorksheetData = [];

        accountWorksheetData.push( {
            "Name" : this.accountName,
            "Industry" : this.accountIndustry,
            "Annual Revenue" : this.accountAnnualRevenue        
        } );
        const accountWorksheet = XLSX.utils.json_to_sheet(
            accountWorksheetData
        );
        XLSX.utils.book_append_sheet(
            workbook, 
            accountWorksheet, 
            'Account Information'
        );

        const tempContactRecords = this.contactRecords;
        for ( const record of tempContactRecords ) {
            
            console.log(
                'record is',
                JSON.stringify( record )
            );
            contactWorksheetData.push( {
                "Id" : record.Id,
                "Name" : record.Name,
                "Email" : record.Email
               
            } );
        }
        const contactWorksheet = XLSX.utils.json_to_sheet(
            contactWorksheetData
        );
        XLSX.utils.book_append_sheet(
            workbook, 
            contactWorksheet, 
            'Contacts Information'
        );

        console.log(
            'Entering write file'
        );
        const excelBuffer = XLSX.write(
            workbook, 
            { bookType: 'xlsx', type: 'array' }
        );
        const blob = new Blob(
            [excelBuffer], 
            { type: 'application/octet-stream' }
        );

        const a = document.createElement( 'a' );
        a.href = URL.createObjectURL(blob);
        a.download = filename;
        a.click();
        URL.revokeObjectURL(a.href);

    }

}

js-meta.xml:

<?xml version="1.0" encoding="UTF-8"?>
<LightningComponentBundle xmlns="http://soap.sforce.com/2006/04/metadata">
    <apiVersion>61.0</apiVersion>
    <isExposed>true</isExposed>
    <targets>
        <target>lightning__RecordAction</target>
        <target>lightning__RecordPage</target>
    </targets>
    <targetConfigs>
        <targetConfig targets="lightning__RecordAction">
            <actionType>Action</actionType>
        </targetConfig>
    </targetConfigs>
</LightningComponentBundle>

Leave a Reply