[SalesForce] How to use VF page to download excel inside Lightning component without redirecting

I have been using a lightning component, on clicking download button. New tab is opened which hit to the vf page url which downloads an excel.
Can we use some other steps of redirection so that the UI remains same and excel gets downloaded.

In VF page, we have wrapper which gets filled by apex class. We dont need to show data in UI. Just one download button to get data.

Thanks

Best Answer

This solution is implemented using Aura framework. I have posted a similar solution using LWC as well.

This is an interesting scenario. In past, I have used download.js to trigger file download from JavaScript.

So I have tried to use the same concept here to download the excel file upon clicking of a button in Lightning UI.

The main idea is to convert the Excel into Base64 encoded String and pass it to the download method of download.js. Which will show the file download window upon the same screen.

Here are my code and screecap in action.

Lightning Component Markup

<aura:component controller="ExcelController" implements="force:appHostable,flexipage:availableForAllPageTypes,force:hasRecordId">
    <aura:attribute name="recordId" type="Id" />
    <lightning:card>
        <ltng:require scripts="{!$Resource.downloadjs}"/>
        <lightning:button variant="brand" label="Download Excel Report" onclick="{! c.downloadExcelFile }" />
    </lightning:card>
</aura:component>

Lightning Component Controller

({
    downloadExcelFile : function(component) { 
        var action = component.get("c.getExcelFileAsBase64String");
        var self = this;
        action.setParams({
            contactId: component.get("v.recordId")
        });
        action.setCallback(this, function(action){
            console.log(action.getState());
            var state = action.getState();
            if(state == 'SUCCESS') {
                var strFile = "data:application/excel;base64,"+action.getReturnValue();
                download(strFile, "myexcelfile.xls", "application/excel");
            }
        }); 
        $A.enqueueAction(action);
    }
})

Apex Class ExcelController

public class ExcelController {
    @AuraEnabled 
    public static String getExcelFileAsBase64String(Id contactId) {
        PageReference excelPage = Page.excelfilepage;
        excelPage.getParameters().put('cid',contactId);
        Blob excelBlob = excelPage.getContent();
        String base64Excel = EncodingUtil.base64Encode(excelBlob);
        return base64Excel;
    }  
}

VF Page to generate Excel

<apex:page controller="contactquery" contentType="application/vnd.ms-excel">
    <apex:pageBlock title="Export Results" >
        <apex:pageBlockTable value="{!cs}" var="contact">
            <apex:column value="{!contact.ID}"/>
            <apex:column value="{!contact.Name}"/>
        </apex:pageBlockTable>
    </apex:pageBlock>
</apex:page>

Apex Class contactquery used for excel generation

public class contactquery{
    public List<Contact> cs{get; set;}
    public contactquery(){
        String cid = ApexPages.currentPage().getParameters().get('cid');
        cs = new List<Contact>();
        for (Contact c : [Select id, Name from Contact WHERE Id =:cid]){       
            System.debug('Inside for '+c);
            cs.add(c);
        }
    }
}

Screencap in action

enter image description here

Related Topic