wkhtmltopdf / wkhtmltopdf

Convert HTML to PDF using Webkit (QtWebKit)

Home Page:https://wkhtmltopdf.org

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

overlapping text when repeating headers/footers in table

rnenjoy opened this issue · comments

commented

When having a big table with lots of rows, or many tables with 10-20 rows, sometimes the feature that repeats the thead/tfoot when there is a page break causes weird results.

Like a tfoot is moved to page one, and is displayed above some other text.

Can this feature be turned off?

Nope, that is a part of the patched QT and can't be controlled. If you want, you can compile your own fork where it is disabled. If you want, post examples of what weird results you are getting -- first check if your HTML is correct.

commented

The HTML:
http://pastebin.com/cMimg5g4

The Header:
http://pastebin.com/s0gyV9Xe

The Footer:
http://pastebin.com/5NU3RmFB

Settings:
'header-html' => 'header.html', 'footer-html' => 'footer.html', 'header-spacing' => 5, 'footer-spacing' => 0

On page 5 of the PDF, we get overlappsed text.

Can you post screenshots? I don't know which platform you are testing this on..

commented

This is on Windows x64 (Windows 2008 R2)

Here is the PDF:
http://www.hymercenter.se/2014-01-31.pdf

Page 5.

Can you check if it works better with the 32-bit version? Also, check if you get better/different results on a Windows XP/7 machine (not server), as there seems to be some issues with Windows Server 2008.

commented

Hello,

I have done some tests.

32/64 bit on Windows Server 2008 produces the exact same problem.

32bit on Windows 7 produces the exact same problem. 64 bit not tested on Win7 as i dont see the issue is there.

@rnenjoy: do you mean to say on Windows 7, 64-bit the issue is not there or you have not tested it?

commented

@ashkulz I have tested it now. Same error on Windows 7 x64.

@rnenjoy: looks like a corner case with the changes made in patched QT by @trvrnrth, will have to investigate it further (unlikely to happen before next week)

commented

@ashkulz thanks for your great work!!

Hi @rnenjoy, @ashkulz,

Unsure if I can offer a solution to this for you, but I found this issue while Google-ing for the same issue.

My table is inside a DIV which has the CSS property overflow-x: auto;

If I switch it to overflow-x: visible; instead this problem goes away.

So assuming you're using the --print-media-type parameter of wkhtmltopdf, you can smash it with a CSS media query so it doesn't affect the browsers output.

@media print {
    .element-that-contains-table {
        overflow: visible !important;
    }
}

Hope that helps you with both a temporary solution and a possible permanent fix for this issue.

@quickstick: I'll make sure to document that, but I don't think it is applicable in the above test case -- it doesn't have an overflow CSS property.

This isn't fixed for me. If I set overflow-x on body to hidden, table headers don't appear to have any height. If I set the thead display property to something like table-cell, the height is fixed, but the header only occupies one cell and causes problems with the rest of the table. If I set the div containing the table to allow overflow, the problem is not resolved.

Ex:

<body>
<div>
<table>
<thead>
<tr>
<th>
</th>
</tr>
<tbody>
<tr>
<td>
</td>
</tbody>
</table>
</div>
</body>
</html>

If I don't hide the x overflow on the body, the table exceeds the page width, and qt scales the contents even if I've specified otherwise with wkhtmltopdf.

@inferiorhumanorgans: I don't think that the issue is solved, hence it is still open.

I found a solution! For printing the report instead of leaving the table footer tag I used it as a a normal tr tag and now it wont repeat the footer of the table.

I can confirm this issue. Can't provide a test-case just yet, but I have one "master table" which contains a single thead, many tbody then one tfoot. For SOME tbody instances (a specific pattern that I'm trying to abstract for the sake of this issue), the content starts at the top of the page, overlapping the thead. For others though, it does not so the issue isn't even consistent within one document except that is a particular type of content. I'll report back if I can find the pattern in a more simplified, repeatable way.

I'm having the same issue. Has there been any update to this or any workaround suggestions? Right now on one of our tables on our production server, text commonly overlaps the table headers.

http://imgur.com/v7DCf2X

It seems that this is also causing the page numbers to be thrown off. The end of the PDF is showing page 63 of 62, 64 of 62, etc.

Do we have a realistic shot of this getting fixed anytime soon, or would you recommend Prince instead?

@gregblass: I haven't gotten a chance to look into this yet, as it is not code written by me. You can try to revert wkhtmltopdf/qt@9df9710 and see if it works for you. I can't say when it will get fixed, but it will be addressed for the next release. If that is not specific enough for you, feel free to try Prince (which is commercial) or FlyingSaucer (java-based) instead, although YMMV.

Thanks for the heads up. Knowing that it will be addressed for the next release at least is great. Prince is very expensive.

@ashkulz Just wondering, do you have a potential timeframe for this next release?

Nope. I work on wkhtmltopdf in my spare time, which has been non-existent lately 😦

Hey,

a workaround for the issue is to split the content of a long <td> block into multiple <tr><td></td></tr>combinations:

instead of:

  <tr>
    <td>
      some
      long
     content
    </td>
  </tr>

write this:

  <tr><td>some</td></tr>
  <tr><td>long</td></tr>
  <tr><td>content</td></tr>

have a look at the resulting pdf:

bildschirmfoto 2014-08-23 um 20 52 21

well, that solved it for me...

@ashkulz Is this fixed in the development snapshot (0.12.2-6a13a51) currently listed on wkhtmltopdf.org? I tried downloading that yet the issue still continues.

I still need to do some thorough testing, but what I think is happening right now is that multiple thead elements are stacking on each other in output. This may be dependent on the respective tables being embedded also though.

@mwmeyer: nope it isn't.

@rainabba: that's possible, but I've yet to confirm that. The best way is to add support for writing the output of QWebFrame::renderTreeDump someplace which can confirm that, but I haven't really gotten time to do that...

I do have the same problem but could not find a workaround too. I am trying to render Invoices from HTML but they really get messed up on the second page (content renders into the table head that gets repeated on the second page) if some of the products in the table do have a long description. I tried different css html combinations but still no success. By the way: @ashkulz Thank you very much for your outstanding work!

Have this invisibile text too when header overlaps on content.
When I've added 'header-spacing' => '50', 'footer-spacing' => '20' my header is disappeared at all.

I was able to work around this by adding top padding to the table head "th"s. The padding gets repeated on each page, which pushes the table out from under the header.

Thanks for the great work on wkhtmltopdf by the way, it's a really useful tool.

Just found a workaround for this, in your CSS use thead, tfoot { display: table-row-group } — This makes them render as normal rows, without attempting to repeat them when there is a page break.

A development snapshot 0.12.2-dev-5dea253 is available, which should fix this issue. Please refer to the breaking changes in this release and report back if your issue is not solved with the above snapshot or there is a regression from existing behavior.

Tested with 0.12.2-dev-5dea253 (recommended 32bit version) on OS X 10.10.1

  1. repeating header enabled (this means NO RULE thead, tfoot {display: table-row-group} )
    bildschirmfoto 2014-11-27 um 14 02 33
    ==> still overlaps - NOT OK
  2. repeating header disabled (this means RULE added thead, tfoot {display: table-row-group} )
    bildschirmfoto 2014-11-27 um 14 08 48
    ==> repeating header is indeed disabled - OK
  3. Table break logic disabled (this means NO RULE tr { page-break-inside: avoid })
    bildschirmfoto 2014-11-27 um 14 11 43
    ==> rows are cut in the middle - OK
  4. Table break logic enabled (this means RULE added tr { page-break-inside: avoid })
    bildschirmfoto 2014-11-27 um 14 18 44
    ==> rows are cut in the middle - NOT OK

Making 1. work would be nice, but until this happens it is good to know that 2. works.
But 4. is a must have...

So I can't see a difference to the previous version (wkhtmltox-0.12.2-dev-200b9a6_osx-carbon-i386)

Post your HTML/CSS for scenario 4.

Here it is
https://gist.github.com/Ognian/573a7fbfc3971b996b3d
I had to extract this in that way since actually this is generated out of a db, even there is a network error: ContentNotFoundError it shows the problem in the pdf files

@Ognian: please produce a reduced test case, it is very difficult to identify an issue. Also let us continue the discussion in #1640 instead. The testcase I used (which works perfectly OK after adding tr { page-break-inside: avoid }) is:

<!DOCTYPE html>
<html>
<head>
    <style type="text/css">
        table { border-collapse: collapse }
        td    { border: 1px solid black; vertical-align: top }
    </style>
</head>
<body>
    <table>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
      <tr>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
        <td>1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ 1234567890 ABCDEF GHIJKL MNOPQ RSTUV WXYZ</td>
      </tr>
    </table>
</body>
</html>

I suspect that your testcase does not work because it has nested tables or colspans, but it is very difficult to go through the HTML.

I had the same problem because I had tr {overflow: hidden !important;} in my print style. Removing that part works great. Thanks for your help guys!

Same problem here. But if I use thead {display: table-header-group} and tfoot {display: table-row-group} the <thead> works fine. Repeating after every page, without any overlap.

Hello, in my test case, adding the following CSS solved the problem:

tr {
    page-break-inside: avoid;
}

@michaelperrin Thanks so much! And thanks to everyone who helped develop this and narrow down the search!

Great!!! That worked for me too! Thanks!!!!

@michaelperrin Thank you, worked for me too.

@ashkulz thank you very much for this great software. We love it.

@michaelperrin Hats Off You... You saved my day..

None of the solutions really helped me. I have large chunks of text sometimes. They even overflow a whole page occasionally. The solution by @michaelperrin will work fine if you do not have large amounts of texts.

So what I did is to solve this, just generate a new <td> for each line of text in my text. Together with @michaelperrin's answer this works nicely. The only drawback is, that new lines will mostly be ignored in your text. But that's acceptable in my use case.

In this case I am using this code in my helper:

  def split_large_text text, max_lines: 8
    if text.lines.length > max_lines
      return text.lines
    else
      [text]
    end
  end

Then this css rules:

.table tbody > tr.borderless
  > td
    padding: 0px
    border: none

This is the final html I have (slim):

table.table
  thead
    tr
      th WID
      th Work Item Description
      th Unit
      th Quantity
      th Price
      th Discount
      th Subtotal
    tbody
    - @report.workitem_table.each do |li|
      tr
        td= li.wid
        td= li.description
        td= li.unit
        td= li.quantity
        td
        td
        td
      - if li.custom_description.present?
        - split_large_text(li.custom_description).each do |chunk|
          tr.borderless
            td.preserve-whitespace-wrap colspan="7"
              = strip_tags(chunk)

@michaelperrin awesome work. thanks!

Is there any ETA of a real solution? We have tables with tekst which overlaps multiple pages

commented

I battled with this for a number of hours, and finally this worked,
thanks to @michaelperrin

tr {
page-break-inside: avoid;
}

the tr { page-break-inside: avoid; } trick by @michaelperrin solved a similar case that was bugging me too. thanks!

If i use the tr { page-break-inside: avoid; } trick with a lot of text i'm getting weird text breaks.

schermafbeelding 2015-07-14 om 09 09 07
schermafbeelding 2015-07-14 om 09 08 28

Yeah, that's a known problem -- see #2141.

commented

For me, on OS X with binary for it, style fix tr { page-break-inside: avoid } works, but doesn't on ubuntu

Hello.

Using version: wkhtmltopdf 0.12.1 (with patched qt)

It is happening also.

Installed with this process.

# cd /tmp
# wget -O wkhtmltox-0.12.1_linux-trusty-amd64.deb http://download.gna.org/wkhtmltopdf/0.12/0.12.1/wkhtmltox-0.12.1_linux-trusty-amd64.deb
# dpkg -i wkhtmltox-0.12.1_linux-trusty-amd64.deb

Thanks.

PS: Temporary solution was use a css that avoid repeate the "tfoot" (gulty of the issue from my PoV)

.wrapfooter tfoot {
    display: table-row-group
}

If a containing element has "overflow: auto", page breaking of tables doesn't work, and the repeated thead and tfoot overlap the tbody. I changed the CSS to "overflow: visible" in my print stylesheet to avoid these problems.

Here's a simple test case based on yours, with HTML and PDF files: http://sam.nipl.net/wkhtmltopdf/

I tested this using wkhtmltopdf 0.12.2.1 (with patched qt). Thanks for your great work!

Your hack worked for me, thanks @nhomar !

.wrapfooter tfoot {
    display: table-row-group
}
tr {page-break-inside: avoid;}

worked for me

preview-51195bd2-850

Not working for me. When text in is enough long, it is overlapping with headers in next page.

I have this same issue and after trying a few suggestions here and on #2367 but finding that nothing was helping I started looking to see what more I could learn about this mis-rendering. I'm using Phantom 1.9 and the text overlays where both the thead and tr occupy the top spot after a page break. Oddly, in Phantom 2.0, for whatever reason, nothing occupies the top spot and there's just an empty space with the designated background color. But the thead is missing, altogether.

A strange thing I just discovered is that by setting a style...
thead th {
height: 2.1cm;
}

The issue is resolved the thead re-render after page break just fine. The really strange thing is that there's no pattern (I can detect) of which measurements work and which don't.

3cm works
2cm fails
2.1cm works
1.1cm works
1.5cm fails
1cm fails

If I can find the patten or reason I'll update my post here. For those of you struggling with this issue you may want to try setting a height and see what happens.

Let me know what you find?

Note: Phantom 1.9 is about three years old now and uses a webkit with no support for page-break-inside.

thanks to @michaelperrin, this works for me:

tr {
page-break-inside: avoid;
}

tr { page-break-inside: avoid; } Does not work for me. I get random breaks and tbody overlaps thead on subsequent pages. Problem has existed for a few versions, but I'm presently on 0.12.2-dev-5dea253 (with patched qt)

Just tried to test with 0.13.0-alpha-7b36694. In the console I got the following and the resulting PDF is mangled/unusable and reported bad by Adobe. :/

(ERROR) WKHTML ERROR ---------------------------

'Qt: Untested Windows version 10.0 detected!\r\n'
(ERROR) WKHTML ERROR ---------------------------

'Qt: Untested Windows version 10.0 detected!\r\n'
(ERROR) WKHTML ERROR ---------------------------

Just to be clear, for those trying the various suggestions listed here, page-break-inside is only supported from 2.0 and forward. If you're using an older version (like I'm required to) you'll need to consider other options.

2.0 of what?

Oh, my mistake. I had posted the answer on a couple of threads about the same issue. 2.0 was referring to PhantomJS which uses the same engine as wkhtmltopdf, "QTWebkit". From what I'm seeing I'd say the issue is in the engine but I don't know which version PhantomJS 1.9.x (or 2.0) uses. But I do know that it's likely that when an older version of PhantomJS doesn't support an arbitrary CSS feature (in this case, page-break-inside) then that probably holds true for an older version of wkhttopdf. You'd have to research though which of each ties in to what versions of QTWebkit.

Found this. If your page-break-inside isn't working your wk is probably running the same version of webkit. http://qnalist.com/questions/5146321/webkit-534-34-when-was-it-released

@motoservo Your observation about the empty space just got a LOT more interesting to me. Because of this issue, I have started testing a migration over to PhantomJS. All was looking well until I got to this specific use-case where I rely on thead repeating and found the EXACT same issue that WKHTML2PDF has so it's clearly a common issue (QT?). I was researching that issue and landed back here (more than a year after my first comment) so this seems to be a major issue.

My observation: On page 1, where my thead should be is empty, then right below that is my thead and following is the expected content which breaks as it should and then shows my tfoot at the 54th item in my list. That's especially interesting, because on page 2, the same blank spot exists and below it is again the thead BUT now it's covered by the content that SHOULD be there if the blank wasn't there and the list resumes at the 55th item and goes to 118 (64 items) and each following page does the same.

This to me says that the first page is layed out wrong because things don't overlap, but start too far down the page then break correctly. On subsequent pages, space is allocated correctly and the page is broken where it should be BUT the thead is positioned too far down causing the overlaps.

Anyone know of a bug in QT that this might map to?

More interesting still. Using position:relative and top against the table that makes up my entire page, I was able to shift my entire table up to the top of the page, but not everything shifted. My thead has an embedded table in it and then 2 TR elements. That embeded table shifted as expected. the 2 TR elements shifted also, but not as far as expected (they should have moved witth the embeded table) and the tbody moved the same. THEN I see the 2 TR's from my thead in the same place as before I applied the hack so it seems that there's some nasty logic in there breaking in multiple ways, not something that's likely to get hacked easily :/ I'm more convinced than ever that it's QT because I can print to Acrobat just fine with FireFox and IE < 10.

Using position:absolute; top: 0 on my thead caused the thead to appear on only page 1, at the top (though not full width now oddly) and ALL tbody content also starts at the top of the page, breaking as it should. Footers are again a mess and all show on the last page. I feel a pattern emerging.

Setting tbody with position: absolute; top: 0 made more of a mess in some ways, but the tbody DID appear where it should on page 1 and then again, at the absolute top on subsequent pages so clearly the first page receives different logic than subsequent pages.

Using table { margin-top: -1.3125in; } thead > tr { margin-top: -1.3125in; } (1.3125in is the height of my header), I was able to get the header to appear on every page, where expected, mostly without overlapping, but footers are still a mess and there's something else strange going on where some of the TR elements in my THEAD appear twice on the first page and in the wrong position (though the same as the 2nd instance on the first) after page 1. If I remove the margin-top for the table, it becomes clear where the duplicating content is coming from (where it would be without this rule), but the header also doesn't stay at the top so it seems that these TR's in my THEAD (not contained in the sub-table) are rendered twice on page 1; once where they should be and again where they'd be without the margin-top and they appear on every page in that position.

To confirm, the thing that worked for me is:

tr {
page-break-inside: avoid;
}

This resulted in me being able to have a thead which repeated on each page, and didn't overlap the tbody content.

tfoot {display: table-row-group;}
tr {page-break-inside: avoid;}

works for me on 0.12.2.1

@ashkulz

I am also facing this same issue but now it's resolved. The problem with the HTML because i am using multiple nested table in thead. if we avoid to use multiple nested tables in thead it works fine. so i removed the multiple nested tables. Now it's working fine for me.
I hope these info will help you and others.

<style type="text/css"> 
  thead {display: table-header-group;}
   tfoot {display: table-row-group;}
   tr {page-break-inside: avoid;}
</style>
<table width="100%" cellpadding="3" cellspacing="0">
<tr>
  <td valign="top">
    <table width="100%" cellpadding="3" cellspacing="0" border="0" style="repeat-header:yes;">
        <thead class="table-header">
            <tr>
                <td colspan="8"><img src="images/logo.png" width="170px"></td>
            </tr>
            <tr>
                <td>&nbsp;</td>
            </tr>
            <tr>
                <td valign="top" align="left" colspan="8" class="pageHeading" width="100%"><h1>Company Search Results</h1></td>
            </tr>
            <tr>
                <td colspan="8">&nbsp;</td>
            </tr>
            <tr>
                <td valign="top" align="left" colspan="8">
                    <table width="100%">
                        <tr>
                            <td width="11%">
                            <h2 class="pdf-name" style="font-size:11px;">Search Text:</h2></td>
                            <td width="89%"><span style="font-size:13px; display:block; font-family: 'Open Sans', sans-serif;">Company Name</span></td>
                        </tr>
                    </table>
                 </td>
            </tr>
            <tr>
                <td>&nbsp;</td>
            </tr>
            <tr>
                    <td valign="top" align="right">

                    </td>                             
                    <td valign="top" align="left">
                        <h2 class="pdf-name">NAME</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">PRODUCTS USED</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">TITLE</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">COMPANY</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">LOCATION</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">EMAIL</h2>
                    </td>
                    <td valign="top" align="left">
                        <h2 class="pdf-name">CONTACT</h2>
                    </td>

            </tr>
        </thead>
        <tbody class="table-body">
            <tr>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
                     <tr>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
            <tr>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
            <tr>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
            <tr>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
              <td></td>
            </tr>
        </tbody>

        <tfoot class="tfoot" style="display: table-footer-group;">
            <tr>
                <td colspan="8" style="border-bottom:0px;">
                    <table width="100%"><tr><td style="text-align:left; font-size:10px;">Report Date: 12-09-2015</td><td style="text-align:right; font-size:10px;">Page 16 - 182</td></tr></table> 
                </td>
            </tr>
        </tfoot>

    </table>
  </td>
</tr>
</table>

Hi Eyewash1, thanks for the solution
Your solution is working.
tr {
page-break-inside: avoid;
}
but In my HTML some time with the same thing its working something strange I just attached a screen shot please look at this and provide me a solution for this strange type of issue.

pdf-issues

Please provide me a solution for that issue..

I think I've finally found the root issue. I too thought it was nested tables, but I think it ultimately comes down to having a single TR that's too large for a page. When this happens, the content on subsequent pages will overlap the header on them. Worse still is if some content inside that TR can't be broken. Since I suspected the issue was embedded tables, I converted my internal tables to the box model (Flexbox isn't supported, but the 2009 box model is, though it's severely crippled in comparison and this took a full day due to my use of rowspan). I had to use a large vertical div to replicate my rowspan and I still had issues. This is when I realized that it's the large vertical TR causing issues. When I was using an embedded table, the overlap happened, but at least the contents were breaking as expected and all content was shown somewhere. When I replaced with the box model and ended up with an overly tall div, things got worse. The content that exceeded the page height got cut off and the next page started (with the header overlap) with the content that followed the div, meaning not all content was displayed while the embedded table broke at one of the embedded TR's and continued on the next page nicely (albeit, with the header overlap).

I think this is the key behavior to understanding the overlapping header issue and I think I'll now stay with embedded tables, but will have to make efforts to ensure that no TR is larger than the page area available.

Hi,

For those who, like me, struggled to get the page-break-inside: avoid; working: it only worked for me when using them as inline styles directly on the tr elements.
Same for the thead element to repeat, I had to specify display:table-header-group as inline style.
That's on a Debian Jessie with wkhtmltox version 0.12.2.1 from http://wkhtmltopdf.org/downloads.html

@svanpoeck Thank you! Your comment saved my couple of ours 👍

Is there any update on a legit fix for this? Setting the CSS per the above comments isn't working for me. I fixed one case with @rainabba's margin-top solution. But now another has been reported where a page has rows overlapping the headers.

For me this worked:

            thead{
                display: table-row-group;
            }

@ashkulz But this is a workaround, not a solution. Besides I have other issues with tables on wkhtmltopdf 0.12.3 (with patched qt). I know there are no issues like this on the non-patched qt version, but how to get it? Where can I download it from?

many thanks to @michaelperrin for that super easy fix!

This issue is now more than two years old. Is there a proper resolution? Can I help someone concentrate on it by paying for their time to write a proper solution?

@RickMeasham: it's in the patch written by @trvrnrth and I'm not too familiar with it. Given that there is a workaround which disables the functionality and the complexity in analysis, it's not something that's going to get solved soon.

In my case the problem for thead was solved by using these two rules:

thead {
      display: table-header-group;
}

tr {
    page-break-inside: avoid;
}

It seems that the solution proposed by @giordy works!

(It was proposed just 4 hours ago! 😮 😆 )

In my case with the following markup...

<table>
    <thead>
        <tr>
            <th>...</th>
        </tr>
    </thead>
    <tbody>
        <tr>
            <td>...</td>
        </tr>
    </tbody>
</table>

The CSS specified by @giordy seems to have solved my table header overlapping issue.

@giordy solution does work for me as well, but as long as I don't have a --header-html. As long as I specify a header, the table header (on the next page, where the second part of the table split continues) starts to get hidden. Anyone else seeing this?

@marianopeck I'm using the --header-html too and I'm not experiencing problems.
Perhaps you forgot to set a top margin for the page with the -T option.

@giordy yes, sorry you are right, I was missing a --header-spacing. Thank you very much for your workaround!!!

@ashkulz What is this patch from @trvrnrth? Are you saying the bug is in his patch that is now merged in? Or that he has a patch that fixes it?

The repeating table head logic was added by @trvrnrth but was never merged upstream but merged in wkhtmltopdf. Apparently, there are some corner cases in it which cause this overlap but I don't have the time to investigate/re-do his patch.

Thanks @ashkulz. The only pull requests I can see from @trvrnrth are #14 and #15. Both of which are about the external header and footer heights. Not the table headers. And then #3 is related to a base URL problem. Am I missing something else?

(None of the suggested workarounds works for us except for turning off the repeating headings)

Edit Was looking at the wrong project. I assume you mean https://github.com/wkhtmltopdf/qt

Well, it was developed at Gitorious (back then the forked qt was not on Github) and I merged those patches when I took over as maintainer from Jakob.

The reason why it's difficult to fix is because it requires changing in the core rendering logic of WebKit. @trvrnrth took a shortcut approach: insert some blank space before the row being rendered on the next page and then manually render the header cells again in the space. This doesn't work for complex scenarios e.g. nested tables and vertical cells and cannot be fixed too easily due to WebKit's earlier printing architecture -- the newer architecture can possibly help, but a majority of the projects are switching to Chromium/Blink and Qt/WebKit is deprecated/unmaintained.

So yes, it is a complex problem and a solution is not on the immediate horizon 😦

wkhtmltopdf/qt@e4c9c73 seems to address the exact problem I'm having. Is it possible that commit to the qt project hasn't been included in the binaries we're using (wkhtmltopdf 0.12.2.1 (with patched qt))

It's definitely included. Can you post your sample HTML/CSS for reference?

I think I found the bug. Just setting up a Debian virtual machine so I can compile it.

Can you post the patch (git diff)?

@ashkulz Got too late at night. Running through it again in case my brain was addled. Then testing. If all is good I'll send you a pull request and/or a patch file. But in the cold light of day, I might not be as close as I thought. But I'll get it.

Pull request wkhtmltopdf/qt#29 fixes my issue. Longish comment on the commit / pull request explains the problem and thus the solution.

I can provide an example HTML file and the before/after PDF files if you want, but it will have to be direct as I can't share them publicly.

Any update on accepting the pull request? I'd like to be using a sanctioned binary rather than my own!