Generate PDF from Apex Salesforce

by Rijwan Mohmmed
Generate-PDF-from-Apex-Salesforce-techdicer

Hello friends, today we are going to discuss Generate PDF from Apex class in Salesforce. In this article, we will first generate a pdf in the apex class with the help of the Visualforce page and then send this pdf as an attachment in the email notification.

Many times we face this type of issue that we need to create a pdf order bill and send this to email, we do confuse that how can we get pdf in apex. Because we all know we can generate CSV files easily in apex.

generate-pdf-from-apex-salesforce-techdicer12

Check out this for generating CSV: create or generate a csv file in Apex Salesforce

Highlights Points :

  1. Create a pdf by using Visalforce Page (renderas pdf)
  2. Call this Visalforce page from apex class to get pdf
  3. Insert this pdf to salesforce object record related list
  4. Send email with attachment

Step 1: In this step, we create a LWC Component with a button name “Generate PDF And Send Email”. So on clicking this button, we can send an email with an attachment. For records, I create a Picklist of contacts so we can select and send emails.

GeneratePdfAndSendEmail.Html :

<template>
    <div class="slds-tabs_card">
		<div class="slds-page-header">
			<div class="slds-page-header__row">
				<div class="slds-page-header__col-title">
					<div class="slds-media">
						<div class="slds-media__figure">
							<span class="slds-icon_container slds-icon-standard-opportunity">
								 <lightning-icon icon-name="standard:recipe" alternative-text="recipe" title="recipe"></lightning-icon>
                            </span>
						</div>
						<div class="slds-media__body">
							<div class="slds-page-header__name">
								<div class="slds-page-header__name-title">
									<h1>
										<span>Generate PDF from Apex Salesforce</span>
										<span class="slds-page-header__title slds-truncate" title="Recently Viewed">TechDicer</span>
									</h1>
								</div>
							</div>
						</div>
					</div>
				</div>
			</div>
		</div>
	</div> <br/>
    <!-- Start Card for Combobox -->
    <lightning-card  variant="Narrow"  title="Generate PDF from Apex Salesforce" icon-name="standard:account">
        <div class="slds-p-horizontal_medium">
            <lightning-combobox name="types" 
                                label="Type" 
                                value={value} 
                                options={typeOptions} 
                                onchange={handleTypeChange}> 
            </lightning-combobox>
            <br/> 
        </div>
		<div>
			<lightning-button variant="brand" label="Generate PDF And Send Email" 
                              title="Primary action" 
                              onclick={generatePDF} 
                              class="slds-m-left_x-small">
            </lightning-button>
		</div>
    </lightning-card>
    <!---------------------->
</template>

GeneratePdfAndSendEmail.JS :

import {LightningElement, track, wire} from 'lwc';
import fetchRecords from "@salesforce/apex/PDFGenerateCtrl.fetchRecords";
import sendPdf from "@salesforce/apex/PDFGenerateCtrl.sendPdf";
import { ShowToastEvent } from 'lightning/platformShowToastEvent';

export default class GeneratePdfAndSendEmail extends LightningElement {
    @track l_All_Types;
    @track typeOptions;
    @track selectedOption;

    @wire(fetchRecords, {})
    wireData({error, data}) {
        if (data) {
            try {
                console.log(data);
                this.l_All_Types = data; 
                let options = [];
                 
                for (var key in data) {
                    // Here key will have index of list of records starting from 0,1,2,....
                    options.push({label: data[key].Name, value: data[key].Id });
                }
                this.typeOptions = options; 
            } catch (error) {
                console.error('check error here', error);
            }
        } else if (error) {
            console.error('check error here', error);
        }
    }
 
    handleTypeChange(event){
        this.selectedOption = event.target.value; 
    }

    generatePDF(){
        sendPdf({contactId : this.selectedOption})
        .then(res=>{
            this.ShowToast('Success', res, 'success', 'dismissable');
        })
        .catch(error=>{
            this.ShowToast('Error', 'Error in send email!!', 'error', 'dismissable');
        })
    }
    

    ShowToast(title, message, variant, mode){
        const evt = new ShowToastEvent({
            title: title,
            message:message,
            variant: variant,
            mode: mode
        });
        this.dispatchEvent(evt);
    }
}

Step 2: In this step, we create an apex class where we write the logic (pdf.getContent()) for generate a pdf and send emails.

PDFGenerateCtrl.cls :

public class PDFGenerateCtrl {
    public Contact con{get;set;}
    public String currentRecordId{get;set;}

    public PDFGenerateCtrl(){
        currentRecordId  = ApexPages.CurrentPage().getparameters().get('id');
        if(currentRecordId != null && String.isNotBlank(currentRecordId)){
            con = [SELECT Id, Name, Email FROM Contact WHERE Id =:currentRecordId];
        }
    }

    @AuraEnabled(cacheable=true)
    public static List<Contact> fetchRecords(){
        try {
            List<Contact> conList = new List<Contact>();

            conList = [Select id, Name, Email from Contact];              
            return conList;
        } catch (Exception e) {
            System.debug('Exception: '+e.getMessage());
            return null;
        }
    }

    @AuraEnabled
    public static String sendPdf(String contactId) {
        PageReference pdf = new pagereference('/apex/ContactDataPDF?id='+contactId);
        pdf.getParameters().put('id', contactId);
    
        Blob body;
        try {
            // returns page as a PDF
            body = pdf.getContent();
        } catch (Exception e) {
            body = Blob.valueOf('data');
        }

        //insert content version
        ContentVersion CV = new ContentVersion();
        CV.Title = 'TechdicerContact.pdf';
        CV.PathOnClient = 'TechdicerContact.pdf';
        CV.VersionData = body;
        CV.FirstPublishLocationId = contactId;
        insert CV;
        
        Messaging.EmailFileAttachment attach = new Messaging.EmailFileAttachment();
        attach.setContentType('application/pdf');
        attach.setFileName('TechdicerContact.pdf');
        attach.Body = body;

        Messaging.SingleEmailMessage mail = new Messaging.SingleEmailMessage();
        mail.setToAddresses(new String[] {'rijwanmohmmed@gmail.com'});
        mail.setSubject('Generate PDF from Apex Salesforce');
        mail.setHtmlBody('Generate PDF from Apex Salesforce');
        mail.setFileAttachments(new Messaging.EmailFileAttachment[] {attach}); 
        // Send the email
        Messaging.sendEmail(new Messaging.SingleEmailMessage[] {mail});
        return 'Email sent Successfully with PDF.';
   }
}

Step 3: In this step, we create a Visualforce page that is reneder-as pdf and put some info in this.

ContactDataPDF.vfp:

<apex:page Controller="PDFGenerateCtrl" renderAs="pdf">
  
  <h1>Contact Data</h1>
  <p><b>Name :</b> {!con.Name}</p>  
  <p><b>Email :</b> {!con.Email}</p> 
</apex:page>

Output :

What’s your Reaction?
+1
0
+1
0
+1
1
+1
0
+1
3
+1
0

You may also like

4 comments

steve May 4, 2023 - 12:19 pm

Everyone shows how to do this, no one shows a passing test class lol.

Reply
Rijwan Mohmmed May 4, 2023 - 1:16 pm

it’s really simple.

Reply
esachait October 12, 2023 - 10:21 am

Is this code really works??

Reply
Rijwan Mohmmed October 13, 2023 - 4:34 pm

Yes

Reply

Leave a Comment