8

I'm trying to render a HTML table in a Visualvorce page as PDF and I'm having the following issues:

  1. I used the CSS below to display the page in landscape but it doesn't work.

@page { size:landscape; }

  1. When rendering the VF page as PDF, the table is displayed without the colors I added using CSS.

  2. How can I create a button that shows the VF page ready to be printed out?

Thank you very much!

9

The PDF renderer's support of CSS Is limited and some trial and error is nearly always required to get the results you want.

I'm not sure why your colours don't work, I've had no issues with that in the past so you might need to post the CSS and markup to show how you're doing it. The code you're using for landscape is correct, so I'm lead to think that you might have a syntax error somewhere that's breaking everything below a certain point.

Finally, you could open the PDF In an iFrame or similar, but since different operating systems and browser combinations handle things very differently I'd be inclined to just open the page in a new tab and let the user handle it how they'd like to. For instance on my Mac, Firefox asks me to save PDFs or open them in Preview (a local app) whereas Chrome displays PDFs in the browser window.

Update

The following CSS was being used:

table tr:nth-child(4n+2) { background: #ccc; }

Which while valid, is not supported by the PDF renderer. The solution is to apply the selection logic via Visualforce/Apex, using the styleClass parameter to specify a CSS class for the desired rows.

  • Thanks LaceSnr! The CSS is pretty simple as you can see below:<apex:page Controller="APEXcustomDisplay" showHeader="true" > <head> <style> table tr:nth-child(4n+2) { background: #ccc; } } </style> </head> <table border="1"> – Chicho Jul 8 '13 at 13:25
  • Hey @Chicho, that CSS isn't complicated as such, but I'd be surprised if the PDF renderer supported nth-child with expressions like that! You might have to set the styles using styleClass and using vf merge fields to work out the logic. – Matt Lacey Jul 9 '13 at 1:04
  • 2
    I created a styleClass and it keeps the format and design when it's rendered as PDF, thanks! – Chicho Jul 9 '13 at 21:27
  • 2
    Cool, I'll update the answer and then if you could mark it as accepted it'll help others who encounter the same issue. – Matt Lacey Jul 9 '13 at 23:04
3

Both Landscape and 'click to render' are possible and easy, it just took a little digging.

Landscape Orientation

It's controlled using the css attribute @page, but when using @page CSS with Salesforce PDF generation, I have found you must put the css code in a separate stylesheet or the PDF Engine ignores it (or even prints it!)—and include the separate stylesheet using apex:

<apex:stylesheet value="{!URLFOR($Resource.StyleZip, 'basic.css')}"/>

To get landscape in your PDF (which works fine in my tests) you would make your stylesheet file (basic.css in above example) something like:

@page {
size: A4 landscape; /* A4 landscape (297mm×210mm) */ }

There is a nice reference on all of the things you can do with @page like set all page sizes, margins, floating bits, page numbering, headers, footers, even include vector graphics here (although I have not tested everything with the SF PDF engine so it may not do it all):

Introduction to page composition with CSS

Click to Render

To view in HTML with a link to 'Download as a PDF', we need to dynamically change the the page renderAs option using a controller. Fortunately, there is really simple example code for this (which oddly isn't mentioned) in a tutorial page about fonts. See:

Fonts Available When Using Visualforce PDF Rendering

The relevant bits are, VF Page:

<apex:page showHeader="false" standardStylesheets="false" 
    controller="SaveToPDF" renderAs="{! renderAs }">

<apex:form rendered="{! showPrintLink }" style="text-align: right; margin: 10px;">
    <div><apex:commandLink action="{! print }" value="Save to PDF"/></div>
    <hr/>
</apex:form> ...

And controller:

public with sharing class SaveToPDF {

    // Determines whether page is rendered as a PDF or just displayed as HTML
    public String renderAs { get; set; }

    // Determines whether to show the "Save As PDF" interface
    public Boolean getShowPrintLink() {
        return ( (renderAs == null) || ( ! renderAs.startsWith('PDF')) );
    }

    // Action method to "print" to PDF
    public PageReference print() {
        renderAs = 'PDF';
        return null;
    }

}
2

In regards to CSS styling and the @page tag, you can use header stylesheets with pdf, but you need to add the applyBodyTag="false" and applyHtmlTag="false" attributes to your apex:page tag and then code the head and body tags yourself.

<apex:page applyBodyTag="false" applyHtmlTag="false" showHeader="false" renderAs="PDF"
    sidebar="false" readOnly="true"  ...etc...etc >
<head>
<style>
    @page {...}
</style>
</head>
<body>
    .....
</body>
</apex:page>

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.