8

I was curious if I could leverage a standard PDF template or make a custom one that I can then render via Apex somehow. I'm curious if I can either:

  • Render it as a PDF directly in Apex via getContentAsPDF method
  • Embed the template somehow into a VisualForce page

This way, if the client needs to alter the PDF generated, a business user can modify it without needing to know VisualForce.

What I am trying to do is create a Quote (and other supporting records), create a QuoteDocument, and then e-mail the QuoteDocument as an attachment. Basically coding what happens OOB normally for Quotes, but done all at once from a button command, rather than numerous clicks on a standard layout.

I know that with an e-mail, you can attach a template to it and the template will take care of the rest.

I would like to know if I can do something similar with a PDF template (more explicitly the standard template). Again, this way if the client needs to make modifications, they can use an editor, as opposed to having to go through VisualForce (and fail).

3
  • are you talking about PDF templates as Adobe does like in adobe.com/content/dam/Adobe/en/products/acrobat/pdfs/… ? One option is to use Conga Composer which allows PDFs to be built from MS Office docs whose values are filled in at run time; result can be emailed and/or attached to sfdc objects
    – cropredy
    Mar 4 '15 at 21:40
  • No, I'm talking about using the standard Quote Template provided by Salesforce. Mar 4 '15 at 21:46
  • I FINALLY found a way to do it. Once I implement it I will share the answer. Mar 4 '15 at 22:20
7

After nearly giving up and trying to recreate the standard template in VisualForce (ouch!), I somehow managed to find a WordPress article on how to create a PDF with the standard template (or a custom template) created through the UI. It is sort of hacky, but it beats having to recreate a template from scratch!

The article can be found here. I also came up with the pass-through idea from an Andy In The Cloud article found here.

Now one thing to note, I had to create a pass-through page to get this to work. Otherwise, I get the following: Dreaded 7 Dwarf Error And that's a real bad error. Apparently, you cannot create a Quote, then generate a PDF in the same method, even though it won't hit a limit (that I know of).

So I did the following:

First, I create a custom label and populated the value with the the Quote template Id. This can be obtained in the edit view of the template.

Once the label was created, I could access it via Apex, in an easier fashion.

Next, I'd create a pass-through page that can be hit, which will generate the PDF and redirect to the Quote record.

VisualForce

<apex:page  controller="GenerateQuotePDFPassthroughController" showHeader="false" sidebar="false" standardStylesheets="false" action="{!GenerateQuotePDFAndRedirectToQuotePage}">
    Generating Quote PDF and e-mailing to contact...    
</apex:page>

Leveraging the action method for the page, I can create my PDF and redirect to my Quote, however, it'll be so fast, the user won't trully notice the process going through multiple pages.

The Controller Code

public with sharing class GenerateQuotePDFPassthroughController 
{
    private final Id QuoteId = (Id) ApexPages.currentPage().getParameters().get('quoteId');
    private final Id QuotePDFTemplateId = (Id)Label.QuotePDFTemplate;

    public PageReference GenerateQuotePDFAndRedirectToQuotePage()
    {
        GenerateQuoteDocument(QuoteId);
        return new PageReference('/' + QuoteId);
    }

    private void GenerateQuoteDocument(Id quotesId)
    {
        String quoteURL = '/quote/quoteTemplateDataViewer.apexp?id=' + quotesId
            + '&headerHeight=190&footerHeight=188&summlid=' + QuotePDFTemplateId
            + '#toolbar=1&navpanes=0&zoom=90';
        PageReference pageReferenceForPDF = new PageReference(quoteURL);
        QuoteDocument newQuoteDocument = new QuoteDocument(); 
        Blob renderedPDF = pageReferenceForPDF.getContentAsPDF();
        newQuoteDocument.Document = renderedPDF;
        newQuoteDocument.QuoteId = quotesId;
        INSERT newQuoteDocument;
    }
}

Now, to simply use this pass-through successfully, I just redirect to the pass-through after my Quote generation instead of to the record.

return new PageReference('/apex/GenerateQuotePDFPassthrough?quoteId=' + NewOrExistingQuote.Id);

It kind of bothers me that I had to resort in a pass-through page in order for this to work. If there are any other suggestions, I'd love to know.

1
  • I implemented this without a passthrough page by refactoring GenerateQuoteDocument method to have the signature @future(callout=true) public static void May 18 '16 at 15:40

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.