Requirement:
To overcome this limitation, we developed a custom solution which involved creating an apex class called PDFGenerator. This class contains the mechanism to accept the HTML content and renders the PDF accordingly to the HTML specified. It will also attach the PDF file to the record as an Attachment.
PDFGenerator Class :
There was a requirement to generate a PDF file while inserting a new record in Account object and add it as an attachment (On-the-fly).
Challenge:
The main challenge was - when the record is saved, the apex trigger is fired on the account object, but at that time, we are unable to use the PageReference Class methods (generate PDF) within the trigger context, making it difficult to generate PDF with this OOTB Class/Method.
Solution:
To generate PDF, we can use out-of-the-box PageReference Class method and it works only if there is not APEX trigger associated with the object. But if Apex trigger is associated with object while inserting a new record, it won't work.
PDFGenerator Class :
public with sharing class PDFGenerator
{
public static final String FORM_HTML_START = '<HTML><BODY>';
public static final String FORM_HTML_END = '</BODY></HTML>';
public static void PDFGenerator(Account account)
{
String pdfContent = '' + FORM_HTML_START;
try
{
pdfContent = '' + FORM_HTML_START;
pdfContent = pdfContent + '<H2>Account Information in PDF</H2>';
//Dynamically grab all the fields to store in the PDF
Map<String, Schema.SObjectType> sobjectSchemaMap = Schema.getGlobalDescribe();
Schema.DescribeSObjectResult objDescribe = sobjectSchemaMap.get('Account').getDescribe();
Map<String, Schema.SObjectField> fieldMap = objDescribe.fields.getMap();
//Append each Field to the PDF
for(Schema.SObjectField fieldDef : fieldMap.values())
{
Schema.Describefieldresult fieldDescResult = fieldDef.getDescribe();
String name = fieldDescResult.getName();
pdfContent = pdfContent + '<P>' + name + ': ' + account.get(name) + '</P>';
}
pdfContent = pdfContent + FORM_HTML_END;
}catch(Exception e)
{
pdfContent = '' + FORM_HTML_START;
pdfContent = pdfContent + '<P>THERE WAS AN ERROR GENERATING PDF: ' + e.getMessage() + '</P>';
pdfContent = pdfContent + FORM_HTML_END;
}
attachPDF(account,pdfContent);
}
public static void attachPDF(Account account, String pdfContent)
{
try
{
Attachment attachmentPDF = new Attachment();
attachmentPDF.parentId = account.Id;
attachmentPDF.Name = account.Name + '.pdf';
attachmentPDF.body = Blob.toPDF(pdfContent); //This creates the PDF content
insert attachmentPDF;
}catch(Exception e)
{
account.addError(e.getMessage());
}
}
}
Now, we would modify an Apex Trigger, on Account object which will initialize the above created PDFGenerator apex class on the record creation (after insertion).
Account Trigger:
trigger AccountTrigger on Account (after insert)
{
if(trigger.isAfter && trigger.isInsert)
{
for(Account ac : trigger.new)
{
PDFGeneratorcController.PDFGenerator(ac);
}
}
}
This approach would generate a PDF within the context of the trigger, and help you overcome the challenge.
If you have any questions you can reach out our Salesforce Consulting team here.