Header height and positioning header from top of page in wkhtmltopdf

mohitp picture mohitp · Mar 8, 2013 · Viewed 12.6k times · Source

In my application, the user is allowed to define his own headers and margins for printing. For the header, the user can provide the following two fields:

  • (a) Page Top Margin in mm (from top of the page)
  • (b) Header Margin in mm (from top of the page)

The fields (a) and (b) are as shown in the figure below: Margins depiction

For example, if the user provides (a) as 10mm and (b) as 100mm, then the height of the 'Header Region' would be 90mm.

Now the content within the header needs to be aligned at the top of the Header Region.

Is there a way to set the Header Region Height and to top-align the content within this header region.

At present, i am doing the following for the header-html option:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />

    <style type="text/css">
        body 
        {
            border:0; 
            margin: 0;
            padding: 0;
            height: 90mm;  //in actual program, this is set dynamically in PHP
        }
    </style>

    <script type="text/javascript">
    function subst() 
    {
        //process the GET parameters and accordingly set the Header Region text info
    }  
    </script>
</head>

<body onload="subst()">
    <div>
        //text
    </div>
</body>  
</html>

The margin-top option is being set as 100mm.

I have tried setting vertical-align: top for the body CSS, But that too did not work.

The final output that I achieve does not seem to have the Header Region content vertical aligned in either top or middle. It is somewhere a little above the middle of the Header Region.

Answer

mohitp picture mohitp · Mar 9, 2013

Edit: This fix seems to be required only when wkhtmltopdf is installed in a Windows based system.

After lot of trial and error, I observed that the following logic seems to be work:

  • The body element of html-head needs to be set to an height 1.33 times the actual height of the Header Region. (Why? I do not know. This could be due to some QT or wkhtmltopdf way of rendering, but it actually works for all cases, irrespective of the lines in the Header Region content).
  • The immediate (and the only) child element of the body is set to 100% height and to hide the overflowing content

So, the changed code (for the above example) for html-head looks like this:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="utf-8" />

    <style type="text/css">
        body 
        {
            border:0; 
            margin: 0;
            padding: 0;
            height: 120mm;
            /*
            In the actual program this height is calculated dynamically in PHP as
            ($headerMargin - $topMargin) * 1.33
            */
        }

        #master-div
        {
            overflow: hidden;
            height: 100%;
        }

    </style>

    <script type="text/javascript">
    function subst() 
    {
        //process the GET parameters and accordingly set the Header Region text info
    }  
    </script>
</head>

<body onload="subst()">
    <div id="master-div">
        //The actual content goes here
    </div>
</body>  
</html>

I have checked this for atleast 7 to 8 different paper sizes (including setting custom page-width and page-height. Also checked with different Header Region content size (ranging from 1 line to 20 lines).

The only catch is that this logic of 1.33 times the header region height seems to work only if the Header Margin(b)/Footer Margin is less than or equal to one-third the paper-height. If the margin height goes beyond that the content gets clipped as the margin-height increases. But having such large header-heights would generally not be required, i guess.