Skip to main content

Creating Super Awesome PDF's with Salesforce


Brief intro Salesforce PDF


Salesforce under the hood uses "Flying-Saucer" rendering engine to render the pdf of the fly.
Check out more about Flying-Saucer here :
It basically supports CSS2.1 and minimal features of CSS3.

I would recommend you to go through @Page css properties
and this link for a better understanding
http://www.antennahouse.com/CSSInfo/CSS-Page-Tutorial-en.pdf

Lets get started:

Case1 :
Repeating Header / Footer

In this example we will have our Logo as header and Page number as the footer
 which will repeated in all the pages of the document.


Demo

The Code:
<apex:page renderAs="pdf" standardStylesheets="false" showHeader="false" applyHtmlTag="false" >
   <head>
       
            <style>
            
            @page
            {
                margin-top:70px;
                margin-left:0px;
                margin-right:0px;
               
                size:portrait;              
                background-color:#EDEDED;
                
              
                @top-left
                {
                    content : element(top-left-div);
                    
                }
                @top-center
                {
                    content : element(top-center-div);
                }
                @top-right
                {
                  
                    content : element(top-right-div) ;
                }
                
                
                @bottom-left
                {
                    content : element(bottom-left-div);
                }
                
                @bottom-center
                {
                    content : element(bottom-center-div);
                }
                
                @bottom-right
                {
                    content : element(bottom-right-div);
                }
                
            }
           
            .top-left-div
            {
                position: running(top-left-div);
               
                background-color:#01a3d6;
                
                color:white;
                text-align:left;
               
                border-bottom: 2px solid black;
                padding:17.5px;
              
            }
             .top-center-div
            {
                position: running(top-center-div);
               
                background-color:#01a3d6;
                color:white;
                text-align:center;
                
                
                border-bottom: 2px solid black;
                padding:25px;
                
            }
             .top-right-div
            {
                position: running(top-right-div);
               
                background-color:#01a3d6;
                text-align:right;
                color:white;
                
                
                border-bottom: 2px solid black;
                padding:25px;
            }
            
            .bottom-left-div
            {
                position: running(bottom-left-div);                  
                
                color:#666666;
                
                text-align:left;                
                margin:5px;
               
                        
            }
             .bottom-center-div
            {
                position: running(bottom-center-div);             
               
                color:#666666;
               
                text-align:center;
                margin:5px;
                
                
            }
             .bottom-right-div
            {
                position: running(bottom-right-div);
                
                color:#666666;
                
                text-align:right;
                margin:5px;
               
                              
            }
            
            
            .pagenumber:before 
            {
                 content: counter(page);
            }

            .pagecount:before 
            {
                content: counter(pages);
            }
            
            
            .content
            {
                margin:10px;
                
                
            }
            .pageFont
            {
                font-family: Arial, Helvetica, sans-serif;
            }
            </style>
    </head>
    
    <body>
        <!-- HEADER INFO BEGIN-->
           
            <div class="top-left-div pageFont">
            
                <!-- THE LOGO -->
                <img src="{!URLFOR($Resource.cloudLogo)}" height="30px"  />
                
            </div>
             <div class="top-center-div pageFont">
                TOP - CENTER
            </div>
             <div class="top-right-div pageFont">
                
                   <div>
                     TOP - RIGHT  
                         
                     </div>
            </div>
       <!-- HEADER INFO END-->

        <!-- FOOTER INFO BEGIN-->
             <div class="bottom-left-div pageFont">
                BOTTOM - LEFT
            </div>
             <div class="bottom-center-div pageFont">
                BOTTOM - CENTER
            </div>
             <div class="bottom-right-div pageFont">
                 <span class="pagenumber"/> 
                           |
                 <span class="pagecount"/>
            </div>
       
       
       <!-- FOOTER INFO END--> 

       <!-- CONTENT -->
       <div class="content pageFont"> 
          THE CONTENT IN PAGE 1
         </div>  
        
        
       <!-- NEW PAGE -->
       <div style="page-break-after:always;"/>
   
            <div class="content pageFont"> 
               THE CONTENT IN PAGE 2
            </div>  
         
    </body>
</apex:page>

Case 2 :
Repeating Header / Footer
First Page is LandScape and rest all are in Portrait

Demo

Just add the following CSS to previous code and you are all set !
   @page:first
            {
                size:landscape;
            }


Case 3 :
Repeating Header / Footer
First n Pages is Portrait and rest n in LandScapemode

For this we make use named page selectors.
First 2 pages are in portrait mode and the next 2 are in landscape mode.
The base code remains the same ,the additions are highlighted in blue.

Demo

Code:
   <apex:page renderAs="pdf" standardStylesheets="false" showHeader="false" applyHtmlTag="false" >
   <head>
       
            <style>
            
            @page landscapeMode
            {
                size : landscape;
            }
                       
            
            
            @page
            {
                margin-top:70px;
                margin-left:0px;
                margin-right:0px;
                
                size : portrait;
                
                background-color:#EDEDED;
                
              
                @top-left
                {
                    content : element(top-left-div);
                    
                }
                @top-center
                {
                    content : element(top-center-div);
                }
                @top-right
                {
                  
                    content : element(top-right-div) ;
                }
                
                
                @bottom-left
                {
                    content : element(bottom-left-div);
                }
                
                @bottom-center
                {
                    content : element(bottom-center-div);
                }
                
                @bottom-right
                {
                    content : element(bottom-right-div);
                }
                
            }
           
            .top-left-div
            {
                position: running(top-left-div);
               
                background-color:#01a3d6;
                
                color:white;
                text-align:left;
               
                border-bottom: 2px solid black;
                padding:17.5px;
              
            }
             .top-center-div
            {
                position: running(top-center-div);
               
                background-color:#01a3d6;
                color:white;
                text-align:center;
                
                margin-left:-1px;
                border-bottom: 2px solid black;
                padding:25px;
                
            }
             .top-right-div
            {
                position: running(top-right-div);
               
                background-color:#01a3d6;
                text-align:right;
                color:white;
                
                margin-left:-1px;
                border-bottom: 2px solid black;
                padding:25px;
            }
            
            .bottom-left-div
            {
                position: running(bottom-left-div);                  
                
                color:#666666;
                
                text-align:left;                
                margin:5px;
               
                        
            }
             .bottom-center-div
            {
                position: running(bottom-center-div);             
               
                color:#666666;
               
                text-align:center;
                margin:5px;
                
                
            }
             .bottom-right-div
            {
                position: running(bottom-right-div);
                
                color:#666666;
                
                text-align:right;
                margin:5px;
               
                              
            }
            
            
            .pagenumber:before 
            {
                 content: counter(page);
            }

            .pagecount:before 
            {
                content: counter(pages);
            }
            
            
            .landscapePages
            {
                page : landscapeMode;
            }
               
            
            .content
            {
                margin:10px;
                
                
            }
            .pageFont
            {
                font-family: Arial, Helvetica, sans-serif;
            }
            </style>
    </head>
    
    <body>
        <!-- HEADER INFO BEGIN-->
           
            <div class="top-left-div pageFont">
            
                <!-- THE LOGO -->
                <img src="{!URLFOR($Resource.cloudLogo)}" height="30px"  />
                
            </div>
             <div class="top-center-div pageFont">
                TOP - CENTER
            </div>
             <div class="top-right-div pageFont">
                
                   <div>
                     TOP - RIGHT  
                         
                     </div>
            </div>
       <!-- HEADER INFO END-->
        <!-- FOOTER INFO BEGIN-->
             <div class="bottom-left-div pageFont">
                BOTTOM - LEFT
            </div>
             <div class="bottom-center-div pageFont">
                BOTTOM - CENTER
            </div>
             <div class="bottom-right-div pageFont">
                 <span class="pagenumber"/> 
                           |
                 <span class="pagecount"/>
            </div>
       
       
       <!-- FOOTER INFO END--> 
       
        <!-- POTRAIT PAGES BEGIN -->
            <div class="content pageFont"> 
                  THE CONTENT IN PORTRAIT PAGE 1
                 </div>  
         
           <!-- NEW PAGE -->
            <div style="page-break-after:always;"/>
         
           <div class="content pageFont"> 
                      THE CONTENT IN PORTRAIT  PAGE 2
               </div> 
         
       <!-- POTRAIT PAGES END-->
      <!-- LANDSCAPE PAGES BEGIN -->

       <div class="landscapePages">
           <div class="content pageFont"> 
                  THE CONTENT IN LANDSCAPE PAGE 1
                 </div>  
                
                
               <!-- NEW PAGE -->
               <div style="page-break-after:always;"/>
           
               <div class="content pageFont"> 
                      THE CONTENT IN LANDSCAPE PAGE 2
               </div>                                      
      </div> 
              <!-- LANDSCAPE PAGES END -->
     </body>
</apex:page>

Happy Coding !!!!!

Comments

  1. Hey Pavan, I need to display a tag(DIV) content (Payment adivce of the invoice which users can tear it off) in the bottom of the last page of the PDF(i.e. Above the footer).
    Could you please help me in doing that I've been struggling to fix that thing from past week

    ReplyDelete

Post a Comment

Popular posts from this blog

Restricting the file types upload in salesforce chatter

Restricting the file types upload in salesforce chatter To restrict the file types one option is to write a trigger on "Feeditem". Developing the Trigger: Open developer console ,go to "File"---> "New" --->"Apex Trigger". From the pop-up give the name of the trigger and choose the sObject as "FeedItem" from the dropdown and hit "Submit" Start Coding !! //TRIGGER TO RESTRICT FILE TYPES ON CHATTER trigger restrictFileType on FeedItem (after insert) {                   for(FeedItem fi : Trigger.new)                    {                                  if(fi.ContentType == 'text')                                            fi.addError('You are not allowed to upload this kind of file');                    } } You can further enhance the code by adding multiple file types in custom settings and refer it in the trigger instead of hardcoding in the trigger. Happy Coding !!!!!

Modal popup on click of custom button

Sometimes u need to display some extra information on click of a custom button in a standard salesforce button but a simple javascript alert wouldnt serve the purpose. In some scenarios you need to display some visualforce page and perform some operations . In many scenarios this custom popup modal window will come to your rescue ! To create this pop first create a custom button. For this example I am going to create a custom button opportunity Go to "Opportunities"------>"Buttons, Links, and Actions". Click on "New Button or Link" Type in the label and description for the button For " Display Type " choose "Detail Page Button" For "Behavior" choose "Execute Javascript" For "Content Source" choose "OnClickJavascript" In the code section paste the following code. {! REQUIRESCRIPT(" https://ajax.googleapis.com/ajax/libs/jquery/1.8.3/jquery.min.js ")} function show