---
title: BULK Butler – Bulk Document Creation from a Salesforce Report with optional saving to SharePoint Folder
description: "Bulk Butler offers you a simple way to generate document for each record from your Salesforce Report. You can also save these generated documents in a SharePoint folder using Collaboration Butler. ##### Example: [Bulk Document Creation from a Salesforce Report…"
url: "https://pdfbutler.com/academy/bulk-butler-academy/bulk-butler/bulk-butler-bulk-doc-creation-from-a-salesforce-report-with-optional-saving-to-sharepoint-folder/"
updated: "2025-06-04"
category: BULK BUTLER
---

# BULK Butler – Bulk Document Creation from a Salesforce Report with optional saving to SharePoint Folder

Bulk Butler offers you a simple way to generate document for each record from your Salesforce Report. You can also save these generated documents in a SharePoint folder using Collaboration Butler.

##### Example:

[Bulk Document Creation from a Salesforce Report with optional saving to SharePoint Folder](https://www.youtube.com/embed/TrpEuv0UIfE)

 Instead of navigating to every opportunity record and generating the document using Doc Config, you want to generate document for all opportunity records you are owning in a single click. You can do this by following a few steps.

###### Salesforce Report

Create a Salesforce report that will fetch the opportunities owned by you. You can add any criteria and fetch the records according to your requirement. Make sure to add Opportunity Id in the first column, so that Apex class can recognize all the Ids for which Bulk Butler want to generate the document.

###### Batch Info Record

Create Batch Info record. Make sure to select Delivery option as BASE64 as we are saving the documents to SharePoint. More information on how to created Batch info record is [here](https://pdfbutler.com/academy/bulk-butler-academy/bulk-butler/bulk-butler-initial-setup/). Once you set up Bulk Butler, the Batch Info tab appears in the App Launcher. You can also enable this object in your PDF Butler App. The Apex class passes the `recordIds` variable to the SOQL and Count SOQL fields.
 ![Bulk doc generation from salesforce report pic1](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic1.png)

###### Apex Class

Create an Apex class, to be called by the screen flow. "recordIds" is set in apex class by querying Salesforce report data as shown below in the code.

```
public class GetReportRecordsAndLaunchBatch {  
    @InvocableMethod(label='Call Bulk Butler Batch Class' description='Invocable to Call batch class which generates PDF for all the records of a Salesforce report')
    public static void callexecute(List<flowinputs> flowinputs) {
        //GetReportRecordsAndLaunchBatch gogogo = new GetReportRecordsAndLaunchBatch();
        executebatch(flowinputs[0].reportName , flowinputs[0].batchInfoId );//pass batch info record id
    }

    public static void executebatch(String reportApiName, Id batchInfoId) { 

        Report rep = [SELECT Id FROM Report WHERE DeveloperName = :reportApiName OR Name = :reportApiName];
        // Run a report synchronously
        Reports.reportResults results = Reports.ReportManager.runReport(rep.Id, true);
        Reports.ReportMetadata rm = results.getReportMetadata();
        String factMapKey = 'T!T';

        // Get the fact map from the report results
        Reports.ReportFactWithDetails factDetails = (Reports.ReportFactWithDetails)results.getFactMap().get(factMapKey);
        System.debug('factDetails: ' + factDetails);      
        List<Id> recordIds = new List<Id>();

        for(Reports.ReportDetailRow detailRow : factDetails.getRows()) {
            Integer index = 0;
            Map<String, Object> row = new Map<String, Object>();
            //First column is the Id we want
            Reports.ReportDataCell cell = detailRow.getDataCells()[0];
            recordIds.add(cell.getLabel());
        }      

        Map<String, Object> inputMap = new Map<String, Object>();
        inputMap.put('recordIds', recordIds);
        if(!Test.isRunningTest())
        	cadmus_batch.Batch_ProcessController.startBatch(batchInfoId, inputMap);
    }
    public class flowinputs {
        @InvocableVariable(label='Batch Info Id')
        public String batchInfoId;
        
        @InvocableVariable(label='Report Name')
        public String reportName;            
    }
}
```

```
@isTest(SeeAllData=true)
public class GetReportRecordsAndLaunchBatchTest {
    private static testMethod void doTest() {
        Test.startTest();
        cadmus_core__Doc_Config__c docconfig = new cadmus_core__Doc_Config__c();
        insert docconfig;
        cadmus_batch__Batch_Info__c cd = new cadmus_batch__Batch_Info__c();
        cd.Name = 'test';
        cd.cadmus_batch__Doc_Config__c = docconfig.Id;
        cd.cadmus_batch__Cron__c='0 0 13 * * ?';
        insert cd;
        
        GetReportRecordsAndLaunchBatch.flowinputs flin = new GetReportRecordsAndLaunchBatch.flowinputs();
        flin.reportName = 'Demo_Report_for_getting_data_via_Apex_fcG';
        flin.batchInfoId=cd.Id;
        List<GetReportRecordsAndLaunchBatch.flowinputs> flnlist = new List<GetReportRecordsAndLaunchBatch.flowinputs>();
        flnlist.add(flin);

        GetReportRecordsAndLaunchBatch.callexecute(flnlist);

        Test.stopTest();
    }
}
```

###### Screen Flow

Create a screen flow as shown below. Create recordId input variable to capture Batch Info record Id.
 ![Bulk doc generation from salesforce report pic5](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic5.png)

Add the screen element with input field "Report Name" to capture the Salesforce report for which you want to generate the documents in bulk.
 ![Bulk doc generation from salesforce report pic4](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic4.png)

Call the Apex action which has been created in previous step and pass input variable "recordId"(which holds Batch Info record id) and Report Name from the screen element as Inputs to the Apex action as shown below.
 ![Bulk doc generation from salesforce report pic6](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic6.png)

Display a confirmation message on the final screen to notify the user that the system has triggered the batch class and where to check the status.

![Bulk doc generation from salesforce report pic7](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic7.png)

###### Button on Batch Info Object

Create a Button that will call Screen flow and add it to Batch Info page.
 ![Bulk doc generation from salesforce report pic3](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic3.png)

###### Actionable record to save in SharePoint folder

Setup Collaboration butler if you haven't done already. Create an Actionable record of type Upload To SharePoint under the Batch Info record. This Actionable will insert documents directly to the SharePoint library and path which you have mentioned as shown below.

Class to Use : cadmus_una.Actionable_CollabStoreFile ![Bulk doc generation from salesforce report pic2](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic2.png)

###### Testing

Now open the Batch Info record and click on the button. Give Report's Unique Name and click on invoke. This will call the apex class to run a batch process which will automatically insert document generated for every record of the salesforce report in the SharePoint path.

![Bulk doc generation from salesforce report pic8](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic8.png)

![Bulk doc generation from salesforce report pic9](https://pdfbutler.com/wp-content/uploads/2025/06/Bulk-doc-generation-from-salesforce-report-pic9.png)

 
