8

I am trying to create a Visualforce page that renders as PDF. My problem is that I want to display as much of a rich text field as can fit. If I use overflow: hidden in my CSS, the text is displayed, but I get blank pages that would be where the additional content would go if it weren't hidden. I can even drag and select the hidden text on the PDF.

Is there a way to use CSS in a VF page rendered as PDF to actually cut the text off?

<apex:page renderas="pdf" standardController="Account" showHeader="false" applyhtmltag="false">
    <head>
    <style>
    @page { 
        size: 8.5in 11in;
        @top-right {
            content: 'Page ' counter(page) ' of ' counter(pages);
            font-style: bold;
        }
    }
    h1 {
        max-height: 200px;
        overflow: hidden;
    }
    </style>
    </head>
    <h1>{!Account.Description}</h1>

</apex:page>
3
  • Have you tried putting it in a table?
    – crmprogdev
    Commented Jul 21, 2014 at 22:05
  • I strongly suspect that you don't have a well enough defined "container" for the postscript engine to know to only reserve the equivalent of 200px. So instead, it's allocating space for the entire content, then not printing the content that exceeds the 200px because it sees the content first instead of the container. If not a table, you probably at least need to have a Div or Span to define the container.
    – crmprogdev
    Commented Jul 21, 2014 at 22:20
  • My actual page is a lot more complicated of course. This was a simplified version that demonstrates the same thing. It doesn't seem to matter what container I put the text in. It always gives me blank pages if the text overflows. Commented Jul 21, 2014 at 23:08

2 Answers 2

2

Based on this SO answer it seems like you need to explicitly specify the width of the container.

enter image description here

<apex:page renderas="{!BLANKVALUE($CurrentPage.parameters.r, 'html')}" standardController="Account" showHeader="false" applyhtmltag="false">
    <head>
    <style>
    @page { 
        size: 8.5in 11in;
        @top-right {
            content: 'Page ' counter(page) ' of ' counter(pages);
            font-style: bold;
        }
    }

    span {
        border: solid 2px blue;
        display: block;
        max-height:200px;

        overflow: hidden;
        width: 7in;
    }
    </style>
    </head>
    <body>
        <span>{!Account.Description}</span>
        <p>{!Account.Name}</p>
    </body>
</apex:page>
6
  • I don't think your text is large enough to cause a page overflow. When I copy and paste your code, I get 5 pages, 4 of which are blank. Commented Jul 22, 2014 at 14:05
  • Although I did learn something. I love the way you handle the renderas. Commented Jul 22, 2014 at 14:06
  • I have 7x lorem ipsum in that acc's description :/
    – eyescream
    Commented Jul 22, 2014 at 15:17
  • So, if you take off the css, does it print more than one page? Commented Jul 22, 2014 at 16:02
  • The pdf ceased to render for me now, even your vanilla version or a really simple page... Maybe I've broken something in my dev org.
    – eyescream
    Commented Jul 23, 2014 at 9:47
1

I still believe per my comments above that your issues are related to "containers". I'm trying to set aside a bit of time to test some variations of what I'm going to share with you, but wanted to post it and some references in the mean time since I know you're also working on this.

Background: Essentially, you're "printing" a document to a PDF printer as pages. As such, containers are even more important to consider, both in terms of a page level and a box level. See W3 Org's Introduction to Paged Media for more on this model.

The W3 specs allow you to specify different CSS for the media type you're outputting to and also for Paged Media (usually print and projection) using @page and for multiple output on different via different display methods using the @media method in your CSS. Below is a simple example:

@media print {
    body { font-size: 10pt }
  }
  @media screen {
    body { font-size: 13px }
  }
  @media screen, print {
    body { line-height: 1.2 }
  }

Your specific issue though is related to orphans and widows that are being created within "boxes" when your overflow isn't being hidden as your CSS has called for which then causes pagination to occur.

In your case, these are being created when hidden text at one of the following below causes an allowed page break to occur:

  • Between line boxes inside a block container box.
  • Between the content edge of a block container box and the outer edges of its child content (margin edges of block-level children or line box edges for inline-level children) if there is a (non-zero) gap between them

These are controlled by page-break-before, page-break-after and most importantly, page-break-inside, all of which are set to auto by default. I think you want to use page-break-inside:avoid. These settings are also impacted to some extent by the orphans and widows setting (min no lines at start of a page and max no lines remaining at end of a page) for your smallest inner "container" or "block" that you're using.

You may also want to note the following per this reference: http://www.w3.org/TR/CSS21/visuren.html#fixed-positioning and see if it can be of any use to you.

For paged media, boxes with fixed positions are repeated on every page. This is useful for placing, for instance, a signature at the bottom of each page. Boxes with fixed position that are larger than the page area are clipped. Parts of the fixed position box that are not visible in the initial containing block will not print.

In summary, I think creating your page based on a page container block model may be the way to solve your issue. I've never been in the situation where I needed to hide overflow text like you're in, so have never encountered this issue. Instead, I've always had the opposite one to deal with; making certain it was all visible.

When I find time to test this further, I'll report back with my findings.

2
  • Thanks for all the time and thought you've taken with this answer. I've tried putting the text in tables, divs and several other containers and I continue to get the text hidden on the page. (I can drag to highlight and select the text) Commented Jul 23, 2014 at 19:34
  • That's useful information to have. It indicates that the text was printed as "invisible" or as the same color as the background!
    – crmprogdev
    Commented Jul 23, 2014 at 19:36

You must log in to answer this question.

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