---
title: Collaboration Butler – Retrieve Files from SharePoint and Merge Use Case
description: "##### **Retrieve Files from SharePoint and Merge:** Let’s say, you have a SharePoint folder with the list of opportunities as sub folders. Consider, the sub folders names are the names of your opportunities in Salesforce Org. To retrieve files based…"
url: "https://pdfbutler.com/academy/collaboration-butler-academy/collaboration-butler-for-sharepoint/collaboration-butler-retrieve-files-from-sharepoint-and-merge-use-case/"
updated: "2026-03-30"
category: COLLABORATION BUTLER for SHAREPOINT
---

# Collaboration Butler – Retrieve Files from SharePoint and Merge Use Case

##### **Retrieve Files from SharePoint and Merge:**

Let’s say, you have a SharePoint folder with the list of opportunities as sub folders. Consider, the sub folders names are the names of your opportunities in Salesforce Org. To retrieve files based on the opportunity name from SharePoint, follow these steps.

###### **Retrieve Files****:**

- Open an opportunity and edit the page
   ![Retrieve Files](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files.png)
- Search for “Collaboration” and Drag the component COLLABORATION Butler (O365 Edition) anywhere on to the page, according to your requirement.
   ![Retrieve Files1](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files1.png)
- Set the fields as below
   • **Site Library URL**
   Set the full URL to your site Library. In this example, this is nothing but the complete URL of the SharePoint folder where your opportunities sub folders are residing. This can be dynamic. You can create a field on opportunity object and enter the URL values in this field for every opportunity record and refer it in the URL.
   Example:
   https://.......com/sites/C......o/Shared Documents
   • **Path to Directory**
   This is the path to the directory where your opportunity related files are being stored. Append the mergefield [[!Name!]] to this path, so that collaboration butler will only retrieve the files based on the opportunity name. If you want to use any custom field instead of standard field “Name”, you can refer that custom field as well.Example:/C....st/C......s/[[!Name!]]
   ![Retrieve Files2](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files2.png)
   ![Retrieve Files3](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files3.png)
   You can set below options according to your requirements
   ![Retrieve Files4](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files4.png)
- Once done, save the page.

###### **Testing** 

You might have already setup and configured the Collaboration Butler. You can login to the SharePoint from any opportunity and the files will be retrieved automatically. 

Refer below academy article for setting up
 [https://pdfbutler.com/academy/collaboration-butler-academy/](https://pdfbutler.com/academy/collaboration-butler-academy/) 

![Retrieve Files5](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files5.png)

Once logged in, all documents of the opportunity will be synced to salesforce from SharePoint.

![Retrieve Files6](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files6.png)

 

###### **Merging your SharePoint PDF documents** 

If you would like to merge SharePoint PDF Documents, we have implemented a custom solution for this. 

Custom Solution involves creation of following components: 

1. Apex classes to fetch files from SharePoint and merge the selected files

```
public class CheckboxChoice { 
    @AuraEnabled 
    //@InvocableVariable(label='Choice Value') 
    public String value; 

    @AuraEnabled 
    //@InvocableVariable(label='Choice Label') 
    public String label; 

    public CheckboxChoice(String value, String label) { 
        this.value = value; 
        this.label = label; 
    } 
}
```

```
public class getFilesFromSharePoint { 
    
    @InvocableMethod(label='Get Files From SharePoint' description='Get Files From SharePoint') 
    public static List<FlowOutput> getFiles(List<flowinputs> flowinputs) { 

        Opportunity opp =[Select Id, Name from Opportunity where Id=:flowinputs[0].recordId]; 
        cadmus_una.MSGraphClient cli=new cadmus_una.MSGraphClient();  
        cli.prepareRefreshToken(UserInfo.getUserId());  

        cadmus_una.CollabMSGraphClient.GetDriveResponse gdr = cli.getSiteDrive(UserInfo.getUserId(),flowinputs[0].libraryUrl); 
        cadmus_una.CollabMSGraphClient.GetDriveContentResponse response =    cadmus_una.CollabMSGraphClient.getDriveItemsByPath(UserInfo.getUserId(), gdr.data.id, flowinputs[0].path+'/'+opp.Name);  

        List<FlowOutput> outputs = new List<FlowOutput>();         
        FlowOutput output = new FlowOutput();                 

        List<List<CheckboxChoice>> allChoices = new List<List<CheckboxChoice>>(); 
        List<CheckboxChoice> choices = new List<CheckboxChoice>(); 

        for (cadmus_una.MsGraphContentResponse.Value value : response.data.value) {     
            choices.add(new CheckboxChoice(value.name, value.name));            
        }  

        output.filechoices = choices; 
        outputs.add(output); 
        return outputs; 
    } 

    public class flowinputs { 
        @InvocableVariable(label='libraryUrl') 
        public String libraryUrl; 

        @InvocableVariable(label='recordId') 
        public String recordId; 

        @InvocableVariable(label='Path') 
        public String path;               
    } 

    public class FlowOutput {        
        @InvocableVariable(label='filechoices') 
        public List<CheckboxChoice> filechoices; 
    }        
}
```

```
public class mergeselectedFileFromSharePoint{ 

@InvocableMethod(label='Merge Selected Files From SharePoint' description='Merge Selected Files From SharePoint') 
    public static void mergeFiles(List<flowinputs> flowinputs) { 
        Opportunity opp =[Select Id, Name from Opportunity where Id=:flowinputs[0].recordId]; 
        system.debug(flowinputs[0].selectedFiles); 
        List<String> selectedFiles = new List<String>(); 
        selectedFiles = flowinputs[0].selectedFiles.split(';'); 
        List<Blob> docs = new List<Blob>(); 
        List<filedata> filedataList = new List<filedata>(); 
        cadmus_una.MSGraphClient cli=new cadmus_una.MSGraphClient();  

        cli.prepareRefreshToken(UserInfo.getUserId());  
        cadmus_una.CollabMSGraphClient.GetDriveResponse gdr = cli.getSiteDrive(UserInfo.getUserId(),flowinputs[0].libraryUrl); 
        Map<String,blob> mapOfFileNameAndBlob = new Map<String,blob>(); 

        for(String str : selectedFiles){            
            cadmus_una.CollabMSGraphClient.GetFileResponse resp = cli.getFile(UserInfo.getUserId(),  
                                                                                 flowinputs[0].libraryUrl,  
                                                                                 true, flowinputs[0].path+'/'+opp.Name+'/'+str);  

            if(resp.isError()) {  
                System.debug(LoggingLevel.ERROR, resp.error + ': ' + resp.error);  
            } else {  
                mapOfFileNameAndBlob.put(str,resp.data);  
            }                          
        } 

        for(String str1: selectedFiles){ 
            cadmus_una.CollabMSGraphClient.GetDriveResponse di=cadmus_una.CollabMSGraphClient.getDriveItemByPath(UserInfo.getUserId(),  
                                                                                                                 gdr.data.id, flowinputs[0].path+'/'+opp.Name+'/'+str1);  
            if(di.isError()) {  
                System.debug(LoggingLevel.ERROR, di.error);  
            } else {   
                filedata fd = new filedata(); 
                fd.fileName=str1; 
                fd.fileURL = di.data.downloadUrl; 
                fd.fileBlob = mapOfFileNameAndBlob.get(str1); 
                filedataList.add(fd); 
            } 
        } 

        cadmus_core.UtilClasses.PdfMergeInput pdfMergeInput = new cadmus_core.UtilClasses.PdfMergeInput(); 
        pdfMergeInput.documents = new List<cadmus_core.UtilClasses.PdfMergeDocument>();         

        for(filedata fl : filedataList){                        
            cadmus_core.UtilClasses.PdfMergeDocument tempdoc = new cadmus_core.UtilClasses.PdfMergeDocument(); 
            tempdoc.filename = fl.fileName; 
            tempdoc.base64 = EncodingUtil.base64Encode(fl.fileBlob); 
            tempdoc.downloadUrl = fl.fileURL; 
            pdfMergeInput.documents.add(tempdoc); 
        }        
         
        cadmus_core.UtilClasses.PdfMergeResult result = cadmus_core.ConvertController.mergePdfs(pdfMergeInput); 
         
        System.debug(result.base64); 
        System.debug(result.sharepointUrl);         
 		Blob fileContent = EncodingUtil.base64Decode(result.base64); //this can be the VersionData of a ContentVersion  
        cadmus_una.CollabMSGraphClient.SaveFileResponse response = cadmus_una.CollabMSGraphClient.saveFile(UserInfo.getUserId(), flowinputs[0].libraryUrl, true,  flowinputs[0].path+'/'+opp.Name+'/'+flowinputs[0].mergedFileName+'.pdf', fileContent);  
    }       

    public class flowinputs { 

        @InvocableVariable(label='libraryUrl') 
        public String libraryUrl;        

        @InvocableVariable(label='recordId') 
        public String recordId;          

        @InvocableVariable(label='Path') 
        public String path;         

        @InvocableVariable(label='Selected Files') 
        public String selectedFiles; 
         
        @InvocableVariable(label='Merged File Name') 
        public String mergedFileName;                        
    } 

    public class FlowOutput { 
        @InvocableVariable 
        public String fileName; 
    } 

    public class filedata { 
        public String fileName; 
        public String fileURL; 
        public Blob fileBlob; 
    } 
}
```

2. Create Screen Flow as shown below
 ![Retrieve Files7](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files7.png)

Create below resources in screen flow
 ![Retrieve Files8](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files8.png) ![Retrieve Files9](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files9.png) ![Retrieve Files10](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files10.png)

Drag screen element and add below input text boxes to screen element 
 ![Retrieve Files11](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files11.png)

Add Apex action and choose “'Get Files From SharePoint”. Set all input values to the apex action as below 
 ![Retrieve Files12](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files12.png)

Drag screen element to show success message ![Retrieve Files15](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files15.png)

Drag screen element to your fault path top show error message![Retrieve Files16](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files16.png)

3. Quick action on the object to refer the above flow(In our example, opportunity)

###### ![Retrieve Files17](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files17.png)
 **Testing** 

Open any opportunity and edit the page. Add the above quick action in the page and save it. 

Click on the quick action and below screen will be displayed. Enter your library URL and path in the fields and click on Get Files. This will fetch all the documents from the SharePoint which are related to this opportunity(Apex class will fetch files if the opportunity name is same as the folder name in you SharePoint) 

![Retrieve Files18](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files18.png)

Select files and click on Merge ![Retrieve Files19](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files19.png)
 Merged document will be in Collaboration Butler section and will be uploaded to SharePoint folder as shown below. 
 ![Retrieve Files20](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files20.png)

 

##### **Send out the merged document **

1. Select the merged file from Collaboration Butler section and click on Send email to send out merged files according to your requirements 

Example: Let’s say, you have a Contact field “Primary Contact” on opportunity and you need to send the merged document to that content. 

To do this follow below steps: 

1. Create Data source which will fetch the primary contact details ![Retrieve Files21](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files21.png)
2. Create a pack record and choose any dummy doc config as we are not using doc config here. However that field is mandatory on page layout.
    ![Retrieve Files22](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files22.png)
3. Create a lightning template or email template for the email body and refer this in Actionable record. Create an Actionable record to the pack record as shown below. 
    ![Retrieve Files23](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files23.png)
   ###### **Testing** 

   Open any opportunity and edit the page, go to the collaboration butler component, copy the PDF butler pack Id which was created in step 2 and paste it in the component. Save the page. 

   ![Retrieve Files24](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files24.png)
    Select the Merged file and click on pack action “Send Email” 
    ![Retrieve Files25](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files25.png)

   ![Retrieve Files26](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files26.png)

   The template body which was created in step 3 and the document will automatically populate, add recipients and email can be sent.
    ![Retrieve Files27](https://pdfbutler.com/wp-content/uploads/2026/03/Retrieve-Files27.png)

##### **Sorting Files**

Change the CheckboxChoice apex class code to below 

```
public class CheckboxChoice implements Comparable{ 

    @AuraEnabled 
    //@InvocableVariable(label='Choice Value') 
    public String value; 
    
    @AuraEnabled 
    //@InvocableVariable(label='Choice Label') 
    public String label; 
    
    public CheckboxChoice(String value, String label) { 
        this.value = value; 
        this.label = label; 
    } 
     
    public Integer compareTo(Object obj) { 

        CheckboxChoice other = (CheckboxChoice) obj;  
        // Null safety 

        if (label == null && other.label == null) return 0; 
        if (label == null) return -1; 
        if (other.label == null) return 1; 
 
        // CASE-SENSITIVE sort 

        return label.compareTo(other.label); 
    } 
}
```

Add Sort() method  

```
public class getFilesFromSharePoint { 
     
    @InvocableMethod(label='Get Files From SharePoint' description='Get Files From SharePoint') 
    public static List<FlowOutput> getFiles(List<flowinputs> flowinputs) { 

        Opportunity opp =[Select Id, Name from Opportunity where Id=:flowinputs[0].recordId]; 
        cadmus_una.MSGraphClient cli=new cadmus_una.MSGraphClient();  
        cli.prepareRefreshToken(UserInfo.getUserId());  
        cadmus_una.CollabMSGraphClient.GetDriveResponse gdr = cli.getSiteDrive(UserInfo.getUserId(),flowinputs[0].libraryUrl); 
        cadmus_una.CollabMSGraphClient.GetDriveContentResponse response = cadmus_una.CollabMSGraphClient.getDriveItemsByPath(UserInfo.getUserId(), gdr.data.id, flowinputs[0].path+'/'+opp.Name);  
        List<FlowOutput> outputs = new List<FlowOutput>();         
        FlowOutput output = new FlowOutput();                 
        List<List<CheckboxChoice>> allChoices = new List<List<CheckboxChoice>>(); 
        List<CheckboxChoice> choices = new List<CheckboxChoice>(); 

        for (cadmus_una.MsGraphContentResponse.Value value : response.data.value) {     
             choices.add(new CheckboxChoice(value.name, value.name));            
        }  

        Choices.sort(); - Added here 
        output.filechoices = choices; 
        outputs.add(output); 
        return outputs; 
    } 
     
    public class flowinputs { 

        @InvocableVariable(label='libraryUrl') 
        public String libraryUrl; 
        
        @InvocableVariable(label='recordId') 
        public String recordId; 
         
        @InvocableVariable(label='Path') 
        public String path;               
    } 

    public class FlowOutput {        

        @InvocableVariable(label='filechoices') 
        public List<CheckboxChoice> filechoices; 
    }        
}
```

 
