Visualforce Sample - Extended Print Preview

Using Visualforce is a great way to create extended print previews for your users. When you need a printout of a Salesforce page, the standard print preview is a good starting point. The print preview link in the detail screen of a Salesforce page renders the visible information from that screen. Sometimes, however, you want a little bit more. Here's one approach to doing it.

Standard Print Preview

Take a look at the following detail screen - a custom object called "visit preparation" used to document the preparation activities for an important meeting:

Detail screen of custom object "Visit Preperation"

The standard print preview will look like this:

Standard print preview

But sometimes you need to include more information on the print than just the detail information and the related list information from the current context.

Let's say for example you want to include some detail information from the related objects - from the account object information about the account industry, type and address, from the contact object the phone number and from the opportunity object you want to include information like the opportunity owner, close date, amount, expected revenue, stage and the closing probability.

Custom Print Preview Using Visualforce

The good news is that you can do this easily by creating a Visualforce page and referencing this information through the use of expressions within the page. The result could look like this:

Standard print preview

As you can see, this page carries a lot more information. Let's look at how to do this.

Using expressions to reference fields for related object data

The following screenshot shows the account information section which includes details from the account object like type, industry and city.

Standard print preview

The Code

The code to get this level of information into the "visit preparation" print preview looks like this:

    <apex:pageBlock title="Visit Preparation – Details">
        <apex:pageBlockSection title="Account Information" columns="2">
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Account" for="account"/>
                <apex:outputField id="account" value="{!Visit_Preparation__c.Account__r.Name}"/>        
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Type" for="type"/>
                <apex:outputField id="type" value="{!Visit_Preparation__c.Account__r.Type}"/> 
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Industry" for="industry"/>
                <apex:outputField id="industry" value="{!Visit_Preparation__c.Account__r.Industry}"/> 
            </apex:pageBlockSectionItem>
            ....
            ....
        </apex:pageBlockSection>
        ....
        ....

The general syntax to get to lookup relation object information is

<ObjectName>.<RelationshipName>.<FieldName>

In this specific example

Visit_Preparation__c.Account__r.<FieldName> .

  • Note: custom relationship names, i.e. relationships that are defined by custom reference fields (lookup or master/detail relationships), have the __r suffix. See your enterprise WSDL or use the schema browser in Eclipse to ascertain your relationship names.

The following is the page code section responsible to the opportunity detail information:

        ....
        <apex:pageBlockSection title="Opportunity Information" columns="2">
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Opportunity" for="opportunity"/>
            <apex:outputField id="opportunity" value="{!Visit_Preparation__c.Opportunity__r.Name}"/>        
        </apex:pageBlockSectionItem>
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Owner" for="owner"/>
            <apex:outputField id="owner" value="{!Visit_Preparation__c.Opportunity__r.OwnerId}"/>        
        </apex:pageBlockSectionItem>
         <apex:pageBlockSectionItem >
            <apex:outputLabel value="Close Date" for="closedate"/>
            <apex:outputField id="closedate" value="{!Visit_Preparation__c.Opportunity__r.CloseDate}"/>        
        </apex:pageBlockSectionItem> 
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Amount" for="amount"/>
            <apex:outputField id="amount" value="{!Visit_Preparation__c.Opportunity__r.Amount}"/>        
        </apex:pageBlockSectionItem>        
        ....

This Visualforce source section renders the page as follows:

Standard print preview

Putting it All Together

1. In order to test this Visualforce example, you would have to create a new custom object Visit Preparation first - go to:

Setup | App Setup | Create | Objects and click the button New Custom Object .

Use the following data to create the custom object:

  • Label: Visit Preparation
  • Plural Label: Visit Preparation
  • Object Name: Visit_Preparation
  • Record Name: Visit Preparation Name
  • Data Type: Text

In the optional feature section, mark the checkbox Allow Activities .

The fields on this custom object should be:

  • Account - Lookup Relation (Account)
  • Contact - Lookup Relation (Contact)
  • Opportunity - Lookup Relation (Opportunity)
  • Target - Text Area(255)
  • Agenda - Text Area(255)
  • Notes - Long Text Area(32000)

2. In the second step, create the new Visualforce page for the print preview by going to:

Setup | App Setup | Develop | Pages and click the button New .

Use the following info to create the page:

  • Label: Visit Preparation
  • Name: visitprep
  • Cut & paste the code below into the entry field and save the page.


3. In the third step, go back to the newly created custom object Visit Preparation and create a new custom button:

  • Label: Print Preview
  • Name: Print_Preview
  • Display Type: Detail Page Button
  • Behavior: Display in new window
  • Content Source: Visualforce Page

This will call the Visualforce page from the button with the ID of the displayed Visit Preparation record.


4. The last step is to place the custom button onto the page layout of the custom object Visit Preperation

Complete Visualforce Page Source

For reference purposes, the following is the complete Visualforce source for the extended print preview example in this article:

<apex:page standardController="Visit_Preparation__c" standardStylesheets="true" showHeader="false" sidebar="false" tabStyle="Visit_Preparation__c">
    <table width="98%" border="0" cellpadding="0" cellspacing="0">
    <tr><td align="right"><a href="javascript:window.print();">Print</a></td></tr>
    </table>
    <apex:pageBlock title="Visit Preparation – Details">
        <apex:pageBlockSection title="Account Information" columns="2">
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Account" for="account"/>
                <apex:outputField id="account" value="{!Visit_Preparation__c.Account__r.Name}"/>        
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Type" for="type"/>
                <apex:outputField id="type" value="{!Visit_Preparation__c.Account__r.Type}"/> 
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Industry" for="industry"/>
                <apex:outputField id="industry" value="{!Visit_Preparation__c.Account__r.Industry}"/> 
            </apex:pageBlockSectionItem>
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="City" for="city"/>
                <apex:outputField id="city" value="{!Visit_Preparation__c.Account__r.BillingCity}"/>
            </apex:pageBlockSectionItem>  
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Contact" for="contact"/>
                <apex:outputField id="contact" value="{!Visit_Preparation__c.Contact__r.Name}"/>
            </apex:pageBlockSectionItem>  
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Phone" for="phone"/>
                <apex:outputField id="phone" value="{!Visit_Preparation__c.Contact__r.Phone}"/>
            </apex:pageBlockSectionItem> 
        </apex:pageBlockSection>
        
        <apex:pageBlockSection title="Opportunity Information" columns="2">
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Opportunity" for="opportunity"/>
            <apex:outputField id="opportunity" value="{!Visit_Preparation__c.Opportunity__r.Name}"/>        
        </apex:pageBlockSectionItem>
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Owner" for="owner"/>
            <apex:outputField id="owner" value="{!Visit_Preparation__c.Opportunity__r.OwnerId}"/>        
        </apex:pageBlockSectionItem>
         <apex:pageBlockSectionItem >
            <apex:outputLabel value="Close Date" for="closedate"/>
            <apex:outputField id="closedate" value="{!Visit_Preparation__c.Opportunity__r.CloseDate}"/>        
        </apex:pageBlockSectionItem> 
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Amount" for="amount"/>
            <apex:outputField id="amount" value="{!Visit_Preparation__c.Opportunity__r.Amount}"/>        
        </apex:pageBlockSectionItem>        
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Stage" for="stage"/>
            <apex:outputField id="stage" value="{!Visit_Preparation__c.Opportunity__r.StageName}"/>        
        </apex:pageBlockSectionItem>       
         <apex:pageBlockSectionItem >
            <apex:outputLabel value="Expected Revenue" for="expectedrevenue"/>
            <apex:outputField id="expectedrevenue" value="{!Visit_Preparation__c.Opportunity__r.ExpectedRevenue}"/>        
        </apex:pageBlockSectionItem>                        
        <apex:pageBlockSectionItem >
            <apex:outputLabel value="Probability" for="probability"/>
            <apex:outputField id="probability" value="{!Visit_Preparation__c.Opportunity__r.Probability}"/>        
        </apex:pageBlockSectionItem>       
        </apex:pageBlockSection>
        <apex:pageBlockSection title="Target & Agenda Information" columns="1">
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Agenda" for="agenda"/>
                <apex:outputField id="agenda" value="{!Visit_Preparation__c.Agenda__c}"/>        
            </apex:pageBlockSectionItem> 
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Target" for="target"/>
                <apex:outputField id="target" value="{!Visit_Preparation__c.Target__c}"/>        
            </apex:pageBlockSectionItem>       
            <apex:pageBlockSectionItem >
                <apex:outputLabel value="Memo" for="notes"/>
                <apex:outputField id="notes" value="{!Visit_Preparation__c.Notes__c}"/>        
            </apex:pageBlockSectionItem>           
        </apex:pageBlockSection>
    </apex:pageBlock>

    <apex:pageBlock title="Activities">
        <apex:pageBlockTable value="{!Visit_Preparation__c.Tasks}" var="item">
            <apex:column value="{!item.ActivityDate}"/>
            <apex:column value="{!item.Subject}"/> 
            <apex:column value="{!item.Priority}"/> 
            <apex:column value="{!item.Status}"/> 
            <apex:column value="{!item.OwnerId}"/>     
        </apex:pageBlockTable> 
    </apex:pageBlock> 
    
</apex:page>