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

1 Answer 1

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>
2
  • As always, you saved me again. Thanks for your time.
    – javanoob
    Oct 20, 2019 at 1:29
  • 2
    @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, 2019 at 1:33

You must log in to answer this question.

Not the answer you're looking for? Browse other questions tagged .