How to Merge Pdf in Salesforce

Hello folks, In this blog I will show how can you merge pdf files into one pdf files. You may encounter this issue that your client wants to download all of its attachments and files into one single pdf.

Key Requirements

  • Must Know basic of admin and development in salesforce
  • Must know how to work over LWC in Salesforce
  • Must Know some third party integration process

For fulfilling this requirement I will use PDF-LIB third party library.

Steps

  • Download PDF-LIB JS from here.
  • Get all related file data in base64 format from Apex Controller. For Ex
@AuraEnabled
    public static List<String> getData(String accountId){
        System.debug('ID is '+accountId);
        Map<String,String> mapOfData = new Map<String,String>();
        List<ContentDocumentLink> lsOfCDL = [SELECT Id, LinkedEntityId, ContentDocumentId FROM ContentDocumentLink WHERE LinkedEntityId=:accountId];
        List<Id> tempsId =new List<Id>();
        for(ContentDocumentLink tempLoop:lsOfCDL){
            tempsId.add(tempLoop.ContentDocumentId);
        }
        List<ContentVersion> lsOfCV = [SELECT Id,VersionData,FileExtension FROM ContentVersion WHERE ContentDocumentId=:tempsId];
        List<String> lsOfFiles = new  List<String>();
        for(ContentVersion tempLoopCv :lsOfCV){
            lsOfFiles.add(EncodingUtil.base64Encode(tempLoopCv.VersionData));
            System.debug('File Extension is  '+tempLoopCv.FileExtension);
            if((''+tempLoopCv.FileExtension).toLowerCase() == 'pdf'){
               mapOfData.put(''+tempLoopCv.Id+','+'PDF',EncodingUtil.base64Encode(tempLoopCv.VersionData));    
            }else{
                 mapOfData.put(''+tempLoopCv.Id+','+'PDF',EncodingUtil.base64Encode(tempLoopCv.VersionData));
            }
               
        }
        return lsOfFiles; 
    }
  • Load your Script and Fetch above data into LWC JS using this code.

renderedCallback() {
        loadScript(this, pdflib).then(() => {
        });

        console.log('recode ud  ' + this.recordId)
        if (this.recordId) {
            getData({ accountId: this.recordId })
                .then((result) => {
                    this.docData = JSON.parse(JSON.stringify(result));
                    console.log('Size of File are ' + this.docData.length)
                    this.error = undefined;
//                   this.createPdf()
                })
                .catch((error) => {
                    console.log('error while calling ' + error)
                }
                )
        }
    }
  • Define createPdf where actual work is done.
 async createPdf() {
        const pdfDoc = await PDFLib.PDFDocument.create();
        console.log('pdfDoc is ', pdfDoc)
        if (this.docData.length < 1)
            return


        var tempBytes = Uint8Array.from(atob(this.docData[0]), (c) => c.charCodeAt(0));
        console.log('tempBytes', tempBytes)
        const [firstPage] = await pdfDoc.embedPdf(tempBytes);
        const americanFlagDims = firstPage.scale(0.99);
        var page = pdfDoc.addPage();
        console.log('page is ', page)

        page.drawPage(firstPage, {
            ...americanFlagDims,
            x: page.getWidth() - americanFlagDims.width,
            y: page.getHeight() - americanFlagDims.height - 10,
        });


        if (this.docData.length > 1) {
            for (let i = 1; i < this.docData.length; i++) {
                tempBytes = Uint8Array.from(atob(this.docData[i]), (c) => c.charCodeAt(0));
                console.log('tempBtes>> ', tempBytes)
                page = pdfDoc.addPage();
                const usConstitutionPdf = await PDFLib.PDFDocument.load(tempBytes);
                console.log('After ', usConstitutionPdf, usConstitutionPdf.getPages())
                const preamble = await pdfDoc.embedPage(usConstitutionPdf.getPages()[0]);
                console.log(' Inside page is ', page)

                const preambleDims = preamble.scale(0.95);

                page.drawPage(preamble, {
                    ...preambleDims,
                    x: page.getWidth() - americanFlagDims.width,
                    y: page.getHeight() - americanFlagDims.height - 10,
                });
            }

        }
        const pdfBytes = await pdfDoc.save();
        this.saveByteArray("My PDF", pdfBytes);
    }
    saveByteArray(pdfName, byte) {
        var blob = new Blob([byte], { type: "application/pdf" });
        var link = document.createElement("a");
        link.href = window.URL.createObjectURL(blob);
        var fileName = pdfName;
        link.download = fileName;
        link.click();
    }

saveByteArray method will download the PDF to your local system.

You can get full code here.