1

I have been banging my head against the wall to get the table styling correctly in Visualforce PDF. Here is a simple example of the problem I am facing. Can someone help me with this?

<apex:page renderAs="PDF">
    <table style="width:100%" border="0" cellspacing="0" cellpadding="0">
        <thead cellpadding="0px" cellspacing="0px">
            <tr>
                <th width="35%" style="background-color:red" align="left">Col A</th>
                <th width="15%" style="background-color:blue">Col B</th>
                <th width="25%" style="background-color:red">Col C</th>
                <th width="25%" style="background-color:blue">Col D</th>
            </tr>
        </thead>
        <tbody>
            <apex:outputPanel rendered="{! 1 == 1 }">
                <tr>
                    <td width="35%" style="background-color:red" align="left">Cell A</td>
                    <td width="15%" style="background-color:blue">Cell B</td>
                    <td width="25%" style="background-color:red">Cell C</td>
                    <td width="25%" style="background-color:blue">Cell D</td>
                </tr>
            </apex:outputPanel>
        </tbody>    
    </table>
</apex:page>

Rendered as PDF:

enter image description here

Rendered as html:

enter image description here

2

This happens because <apex:outputPanel? renders an additional <span> tag by default. Here's the generated output of your code:

<table border="0" cellpadding="0" cellspacing="0" style="width:100%">
    <thead cellpadding="0px" cellspacing="0px">
        <tr>
            <th align="left" style="background-color:red" width="35%">Col A</th>
            <th style="background-color:blue" width="15%">Col B</th>
            <th style="background-color:red" width="25%">Col C</th>
            <th style="background-color:blue" width="25%">Col D</th>
        </tr>
    </thead>
    <tbody><span id="j_id0:j_id2">
            <tr>
                <td align="left" style="background-color:red" width="35%">Cell A</td>
                <td style="background-color:blue" width="15%">Cell B</td>
                <td style="background-color:red" width="25%">Cell C</td>
                <td style="background-color:blue" width="25%">Cell D</td>
            </tr></span>
    </tbody>    
</table>

Browsers ignore this, but it confuses the underlying PDF engine (Flying Saucer). In order to avoid this problem, do not use <apex:outputPanel> to render conditional text. Instead, use <apex:outputText> to get the desired behavior, or use the layout="none" attribute to get the <span> to disappear.

<apex:outputText>

<apex:page renderAs="pdf">
    <table style="width:100%" border="0" cellspacing="0" cellpadding="0">
        <thead cellpadding="0px" cellspacing="0px">
            <tr>
                <th width="35%" style="background-color:red" align="left">Col A</th>
                <th width="15%" style="background-color:blue">Col B</th>
                <th width="25%" style="background-color:red">Col C</th>
                <th width="25%" style="background-color:blue">Col D</th>
            </tr>
        </thead>
        <tbody>
            <apex:outputText rendered="{! 1 == 1 }">
                <tr>
                    <td width="35%" style="background-color:red" align="left">Cell A</td>
                    <td width="15%" style="background-color:blue">Cell B</td>
                    <td width="25%" style="background-color:red">Cell C</td>
                    <td width="25%" style="background-color:blue">Cell D</td>
                </tr>
            </apex:outputText>
        </tbody>    
    </table>
</apex:page>

<apex:outputPanel layout="none">

<apex:page renderAs="pdf">
    <table style="width:100%" border="0" cellspacing="0" cellpadding="0">
        <thead cellpadding="0px" cellspacing="0px">
            <tr>
                <th width="35%" style="background-color:red" align="left">Col A</th>
                <th width="15%" style="background-color:blue">Col B</th>
                <th width="25%" style="background-color:red">Col C</th>
                <th width="25%" style="background-color:blue">Col D</th>
            </tr>
        </thead>
        <tbody>
            <apex:outputPanel label="none" rendered="{! 1 == 1 }">
                <tr>
                    <td width="35%" style="background-color:red" align="left">Cell A</td>
                    <td width="15%" style="background-color:blue">Cell B</td>
                    <td width="25%" style="background-color:red">Cell C</td>
                    <td width="25%" style="background-color:blue">Cell D</td>
                </tr>
            </apex:outputPanel>
        </tbody>    
    </table>
</apex:page>
  • As always, you saved me again. Thanks for your time. – javanoob Oct 20 at 1:29
  • 1
    @javanoob Oh, I just noticed you can use <apex:outputPanel>, but you need to use layout="none" to get that span to disappear. I guess the moral of the story is to always check the docs. I'm going to add an edit to that effect, but either way works. – sfdcfox Oct 20 at 1:33

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.