Dynamically choosing whether to render as PDF in Visualforce

It turns out that you can dynamically control whether a Visualforce page is rendered as a PDF or not. This pretty much means you can PDF anything on the platform. I wanted to be able to switch between HTML and PDF easily. Here's how.

It turns out that you can dynamically control whether a Visualforce page is rendered as a PDF or not.

Picture_14Visualforce (coming in a week or two) has this neat feature where you can just set an attribute and have the page rendered as a PDF. This pretty much means you can PDF anything on the platform. What I wanted to do was have a page rendered as standard HTML though, and flick a toggle to have it rendered as PDF. Same page, two output formats. (I’m trying to find a cool demo for this webinar, where I’ll be helping Ron).

The code for my Visualforce page was pretty straightforward. You can see a picture of the result above.
Here’s the output PDF it generates.

Here’s how I did it. I’ve called this page foo.

<apex:page renderAs="{!chooserender}" controller="MyController" >
<apex:pageBlock title="Some Page Block">
<apex:pageBlockSection title="Section 1"> Text </apex:pageBlockSection>
<apex:pageBlockSection title="Section 2"> Text </apex:pageBlockSection>
</apex:pageBlock>
<apex:form>
<apex:commandLink value="PDF" action="{!deliverAsPDF}" target="_blank"></apex:commandLink>
</apex:form>
</apex>

There are two things happening here. The PDF link will make a call out to the deliverAsPDF() method in my controller, and the renderAs attribute (valid choices: “pdf” or null) will make a call out to the getChooseRender() method.

In other words, what I’m going to do is this: when you push the link, I’m going to grab the page, but this time only after ensuring that the renderAs attribute is set to “pdf”. I’m then going to return the PDF, and it will pop up in a new window (target attribute). The way I set the attribute is based on whether a parameter has been passed to the page or not, as you’ll see in the code:

public class MyController {
// return 'pdf' if the parameter 'p' has been passed to the page, other null
public String getChooserender() {
if (ApexPages.currentPage().getParameters().get('p') != null)
return 'pdf';
else
return null;
}
// Go grab the page and pass parameter 'p'
public PageReference deliverAsPDF() {
PageReference pdf =  Page.foo;
pdf.getParameters().put('p','p');
return pdf;
}
}

That’s it! I guess another key thing to realize here in the MVC model is that I can actually manipulate pages from my controller with Apex. ie. Page.foo is a reference to my Visualforce page, and I can do things with it (in this case, pass it parameters).

I believe you can dynamically assign style sheets as well, so you can imagine doing some cool stuff with this like having CSS for the print layout that arranges things more pleasantly etc.

Published
June 5, 2008
Topics:

Leave your comments...

Dynamically choosing whether to render as PDF in Visualforce