Emailing Visualforce Pages Rendered as PDFs

by Jon Mountjoy on June 10, 2008 at 01:38 AM

I blogged the other day about how to dynamically choose whether a Visualforce page is rendered as a PDF or not-useful when creating invoices and so on.  Now I'm going to email that page using a little Apex code.

First, let's define the page:

<apex:page renderAs="{!if($CurrentPage.parameters.p == null, null, 'pdf')}"
           controller="MyController">
    <apex:pageBlock title="My Dual-Rendering Invoice">
        <apex:pageBlockSection title="Section 1"> Text </apex:pageBlockSection>
        <apex:pageBlockSection title="Section 2"> Text </apex:pageBlockSection>
    </apex:pageBlock>
                
  <apex:form >
   <apex:commandLink rendered="{!$CurrentPage.parameters.p == null}"  value="PDF"
            action="{!deliverAsPDF}" ></apex:commandLink>
  </apex:form>

</apex:page>

This is a refinement of the one I blogged last time, using some tips from Doug Chasman.  Note that the outputlink won't render in the final PDF - cool!  The only key thing here is that the page will render as a PDF if a parameter "p" is passed in. Otherwise it renders as HTML.

The question is how to write our getDeliverAsPDF() method to create the PDF and mail it off in an email.  Here's how I coded the controller to do this:

public class MyController {
public PageReference getDeliverAsPDF() {
     // Reference the page, pass in a parameter to force PDF
     PageReference pdf =  Page.foo;
     pdf.getParameters().put('p','p');
     pdf.setRedirect(true);
     // Grab it!
     Blob b = pdf.getContent();
     // Create an email
     Messaging.SingleEmailMessage email = new Messaging.SingleEmailMessage();
     email.setSubject('From getDeliverAsPDF!');
     String [] toAddresses = new String[] {'foobar@youremailaddressz.com'};
     email.setToAddresses(toAddresses);
     email.setPlainTextBody('Here is the body of the email');
     // Create an email attachment
     Messaging.EmailFileAttachment efa = new Messaging.EmailFileAttachment();
     efa.setFileName('MyPDF.pdf'); // neat - set name of PDF
     efa.setBody(b); //attach the PDF
     email.setFileAttachments(new Messaging.EmailFileAttachment[] {efa});
     // send it, ignoring any errors (bad!)
     Messaging.SendEmailResult [] r =
            Messaging.sendEmail(new Messaging.SingleEmailMessage[] {email});   
     return null;
}
}
          

The only tricky bit here is the pdf.GetContent() method, which grabs the rendered PDF content.  I then stuff it into an email attachment and send it off!

 



Technorati Tags:
,


TrackBack

TrackBack URL for this entry: http://www.typepad.com/services/trackback/6a00d8341cded353ef00e5535872da8834

Listed below are links to weblogs that reference Emailing Visualforce Pages Rendered as PDFs:

Comments

Posted by Andreas Schaefer on June 15, 2008 05:08 AM:

very cool! this should also allow me to save the rendered pdf as an attachment to e.g. an opportunity instead of e-mailing it.

Posted by Jon Mountjoy on June 15, 2008 12:05 PM:

Hi Andreas

Because it's simply Apex, you can do a lot of things with the PDF, including adding an attachment like you suggest. To do this, instead of emailing the blob (b) above, I could wrap it in an attachment and insert the new attachment object like so:

Attachment a = new Attachment(parentId =idOfContactOrOppToWhichToAttach, name='JONSATTACHMENT.pdf',body=b);
insert a;

Posted by foo on June 17, 2008 12:36 PM:

Very neat <<< """ \" \<

Posted by Nick on June 26, 2008 05:21 PM:

This looks great.
Does anyone know if you can use this method to set the From address in the email?

Posted by Jon Mountjoy on June 26, 2008 06:48 PM:

Hi Nick

A quick search of our forums yields the answer: no.

See here for an explanation.
http://tinyurl.com/5csrwk

Regards,
Jon

Posted by Mark on January 6, 2009 10:31 AM:

Is there a way to record sending this email into and objects activity history?

Post a comment

If you have a TypeKey or TypePad account, please Sign In