Hello Everyone, I am writing this blog to show you a Lightning component example that helps you to upload single or multiple files at a time. In this example, I am using lighting:fileupload component to make it easily understandable and user-friendly. All files and document that are uploaded with this example are stored in Salesforce files object. So without wasting time, let's get started, 

File upload Lightning Component

Step 1: Login to your Salesforce Org. and open Developer console. 

Step 2: Navigate to File | New | Apex Class and Create an Apex controller called LightingFileUploadHandler. Replace following code in apex controller.  

LightingFileUploadHandler.apxc
 public class LightningFileUploadHandler {
    
    @AuraEnabled  
    public static List<ContentDocument> getFiles(string recordId){ 
        // TO avoid following exception 
        // System.QueryException: Implementation restriction: ContentDocumentLink requires
        // a filter by a single Id on ContentDocumentId or LinkedEntityId using the equals operator or 
        // multiple Id's using the IN operator.
        // We have to add sigle record id into set or list to make SOQL query call
        Set<Id> recordIds=new Set<Id>{recordId};
        Set<Id> documentIds = new Set<Id>(); 
        List<ContentDocumentLink> cdl=[SELECT id,LinkedEntityId,ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId IN:recordIds];  
        for(ContentDocumentLink cdLink:cdl){  
            documentIds.add(cdLink.ContentDocumentId);  
        }      
        return [SELECT Id,Title,FileType FROM ContentDocument WHERE id IN: documentIds];  
    } 
    
    @AuraEnabled  
    public static void deleteFiles(string sdocumentId){ 
        delete [SELECT Id,Title,FileType from ContentDocument WHERE id=:sdocumentId];       
    }  
 }
Step 3: Navigate to File | New | Lightning Component and create a Lightning Component called LightningFileUpload. Replace the following markup in the Lightning Component.

LightingFileUpload.cmp
 <aura:component controller="LightningFileUploadHandler" implements="force:appHostable,flexipage:availableForAllPageTypes,flexipage:availableForRecordHome,force:hasRecordId,forceCommunity:availableForAllPageTypes,force:lightningQuickAction" access="global" >  
    <aura:handler name="init" value="{!this}" action="{!c.doInit}"/>  
    <aura:attribute name="files" type="ContentDocument[]"/>  
    <aura:attribute name="recordId" type="string" default="0010K00001yb8ycQAA"/>  
    <aura:attribute name="accept" type="List" default="['.jpg', '.jpeg','.pdf','.csv','.xlsx']"/>  
    <aura:attribute name="multiple" type="Boolean" default="true"/>      
    <aura:attribute name="Spinner" type="boolean" default="false"/>
    <div class="slds">  
        <lightning:notificationsLibrary aura:id="notifLib"/>
        <div class="contentbox">  
            <div class="slds-page-header header">Files</div>  
            <div class="slds-grid">  
                <div style="width:100%">  
                    <center>
                        <lightning:fileUpload label="" multiple="{!v.multiple}"   
                                              accept="{!v.accept}" recordId="{!v.recordId}"   
                                              onuploadfinished="{!c.UploadFinished}" />  
                    </center>
                </div>  
            </div><br/> 
            <div class="slds-form--compound" style="position:relative">
                <table class="slds-table slds-table--bordered">  
                    <thead>  
                        <tr>  
                            <th></th>
                            <th>Title</th>  
                            <th>FileType</th>                    
                        </tr>  
                    </thead>  
                    <tbody>
                        <aura:iteration items="{!v.files}" var="f">  
                            <tr>  
                                <td><a href="javascript:void(0)" id="{!f.Id}" onclick="{!c.delFiles}">Delete</a></td>
                                <td><a href="" id="{!f.Id}" onclick="{!c.previewFile}">{!f.Title}</a></td>  
                                <td>{!f.FileType}</td>                              
                            </tr>  
                        </aura:iteration>  
                    </tbody>  
                </table>  
                <aura:if isTrue="{!v.Spinner}">
                    <div class="slds-spinner_container">
                        <div class="slds-spinner slds-spinner--medium" aria-hidden="false" role="alert">
                            <div class="slds-spinner__dot-a"></div>
                            <div class="slds-spinner__dot-b"></div>
                        </div>
                    </div>
                </aura:if>
            </div>
        </div>  
    </div>  
 </aura:component>
LightingFileUploadController.js
 ({  
    doInit:function(component,event,helper){  
       helper.getuploadedFiles(component);
    },      
    
    previewFile :function(component,event,helper){  
        var rec_id = event.currentTarget.id;  
        $A.get('e.lightning:openFiles').fire({ 
            recordIds: [rec_id]
        });  
    },  
    
    UploadFinished : function(component, event, helper) {  
        var uploadedFiles = event.getParam("files");  
        //var documentId = uploadedFiles[0].documentId;  
        //var fileName = uploadedFiles[0].name; 
        helper.getuploadedFiles(component);         
        component.find('notifLib').showNotice({
            "variant": "info",
            "header": "Success",
            "message": "File Uploaded successfully!!",
            closeCallback: function() {}
        });
    }, 
    
    delFiles:function(component,event,helper){
        component.set("v.Spinner", true); 
        var documentId = event.currentTarget.id;        
        helper.delUploadedfiles(component,documentId);  
    }
 })  
LightingFileUploadHelper.js
 ({  
    getuploadedFiles:function(component){
        var action = component.get("c.getFiles");  
        action.setParams({  
            "recordId":component.get("v.recordId")  
        });      
        action.setCallback(this,function(response){  
            var state = response.getState();  
            if(state=='SUCCESS'){  
                var result = response.getReturnValue();           
                component.set("v.files",result);  
            }  
        });  
        $A.enqueueAction(action);  
    },
    
    delUploadedfiles : function(component,documentId) {  
        var action = component.get("c.deleteFiles");           
        action.setParams({
            "sdocumentId":documentId            
        });  
        action.setCallback(this,function(response){  
            var state = response.getState();  
            if(state=='SUCCESS'){  
                this.getuploadedFiles(component);
                component.set("v.Spinner", false); 
            }  
        });  
        $A.enqueueAction(action);  
    },  
 }) 
LightingFileUploadStyle.css
 .THIS .contentbox{
    border-left: 1px solid rgb(221, 219, 218);  
    border-right: 1px solid rgb(221, 219, 218);  
    border-bottom: 1px solid rgb(221, 219, 218);  
    border-top: 1px solid rgb(221, 219, 218);
 }

 .THIS .header{
    border-radius: 0px; 
    border-right: 0px;
    border-left: 0px;
    border-top: 0px;  
    box-shadow: 0 0px 0px 0 rgba(0, 0, 0, 0.1);
 }
Step 4: To Create a quick action Navigate to Setup | Object Manager | Account |Buttons, Links and Actions | New Action. Fill all required fields and hit the Save button.


Step 5: To add quick action in account page layout Navigate to Setup | Object Manager | Account | Page Layouts. Edit Account Layout and move to Mobile & Lightning Actions.


Step 6: Drag File Upload quick action in  Salesforce Mobile & Lightning Experience Actions section and save the Account page layout.


Step 7: Open an account record and click on the File upload quick action button.


Output:


See also:

Conclusion:
Hope you like this tutorial, for any query or suggestions please feel free to comment.
Thank you.