How to avoid page break inside table row for wkhtmltopdf

WkhtmltopdfPdfkit

Wkhtmltopdf Problem Overview


I am generating pdf report from html page with one table.

I am using wkhtmltopdf for the purpose.

when pdf is generated it breaks anywhere in tr tag.

I want to avoid it .

Wkhtmltopdf Solutions


Solution 1 - Wkhtmltopdf

Update 17.09.2015: Check the version you are using: wkhtmltopdf 0.12.2.4 is said to fix the problem (I have not checked).


This is a known issue in wkhtmltopdf. The page breaking algorithm used by webkit (the WK in WKhtmltopdf) doesn't really work well for large tables. I suggest breaking the table down to smaller chunks that are more easily split to pages and using the css a lot:

table, tr, td, th, tbody, thead, tfoot {
    page-break-inside: avoid !important;
}

Also have a look at the following wkhtmltopdf issues, they have interesting comments that discuss for example the table splitting problem. There is a JS solution that programmatically splits tables in 168 that might help you (I don't use it though).

Update 08.11.2013 There is much discussion about this in issue 168 linked above. Someone has managed to compile a version of wkhtmltopdf that supports better table breaking, but unfortunately it seems that it's not officially released and might contain other bugs. I don't know how to get it and I don't know how to compile on Windows, but anyone interested can check for example the comment here (see new update below).

Update 24.02.2014 You will be pleased to hear that in wkhtmltopdf 0.12 this feature among others has been greatly improved. However, wait for 0.12.1 and test thoroughly before starting to use any new version, it's still a little unstable although the new guys working on with antialize are doing a Great job (ashkulz rocks)! Keep updated at wkhtmltopdf.org and github. The google code site is obsolete and being slowly migrate.

Solution 2 - Wkhtmltopdf

It is old post, but since i was wasting lot of time trying to find proper solution, i will put it here, maybe it will be useful to someone.

So from what i read, the problem with

page-break-inside: avoid

is that it doesn't work. But actually if you set it on element that has display:block it works as expected (as noted somewhere in SO). so for simple structure of table css with

td div, th div{
    page-break-inside: avoid;
}

and table structure

<table>
....
<tr>
    <td><div>some text</div></td>
    <td><div>more text</div></td>
</tr>
....
</table>

will work as expected.

I had bit more complicated case with rowspans, so the solution from above was breaking it to peaces, which wasn't desired effect. I solved it using divs for each rowspaned set of lines. My jquery js doing all the job:

$(window).load(function () {
	var sizes = {};
	$('#the_table tr:first th').each(function (a, td) {			
		var w = $(td).width();
		if (sizes.hasOwnProperty('' + a)) {
			if (sizes['' + a] < w)
				sizes['' + a] = w;
		}
		else {
		    sizes['' + a] = w;
		}
	});

	var tableClone = $('#the_table').clone();
	$('#the_table').replaceWith('<div class="container"></div>');
	
	var curentDivTable;
	var cDiv = $('.container');
	tableClone.find('tr').each(function (i, ln) {
		var line = $(ln);
		if (line.hasClass('main_row')) {
			var div = $('<div class="new-section"><table><tbody>')
			currentDivTable = div.find('tbody');
			cDiv.append(div);				
		}
		currentDivTable.append(line);
	});
	//optional - maybe in % its better than px
	var sum = 0;
	$.each(sizes, function (a, b) {
		sum += b;
	});
	var widths = {};
	$.each(sizes, function (a, b) {
		var p = Math.ceil(b * 100 / sum);
		widths['' + a] = p + '%';
	});
	//setup
	$('.container table').each(function (a, tbl) {
		$(tbl).find('tr:first td, tr:first th').each(function (b, td) {
			$(td).width(widths['' + b]);
		});
		$(tbl).addClass('fixed');
	});
});

css:

div.new-section {
	page-break-inside: avoid;
}
.container, .new-section, .new-section table.fixed{
	width: 100%;
}

.new-section table.fixed{
	table-layout:fixed;
}

I don't know if everything is needed and I don't think its perfect, but it does the job. Tested on chrome only

Solution 3 - Wkhtmltopdf

Since 0.12 this issue has been solved but, sometimes, when a table is too long to fit in the page, wkhtmltopdf breaks it in two parts and repeats the column headers on the new page and these column headers appear superposed to the first row.

I found a temporal solution to this problem on the wkhtmltopdf github issues section: https://github.com/wkhtmltopdf/wkhtmltopdf/issues/2531

Just add this lines to your view css:

tr {
  page-break-inside: avoid; 
}

Solution 4 - Wkhtmltopdf

I've digged into this problems for days, and finally found the perfect solution. You can reference this project phpwkhtmltopdf. Look into the directory article and you will find 3 solutions for 3 problems. In short, the ultimate solution is add the css style

thead {
    display: table-row-group;
}
tr {
    page-break-before: always;
    page-break-after: always;
    page-break-inside: avoid;
}
table {
    word-wrap: break-word;
}
table td {
    word-break: break-all;
}

If you're Chinese, feel free to check this site关于wkhtmltopdf,你一定想知道这些 Check out the gist if you wish gist for wkhtmltopdf

Solution 5 - Wkhtmltopdf

In my particular case for some reason none of the previous answers worked for me. What ended up working was actually a combination of several things.

  1. I installed (in Ubuntu 16.04) the Wkhtmltopdf python wrapper called pdfkit using pip3, and then instead of installing Wkhtmltopdf via apt-get I installed the static binary (version 0.12.3) by following the script below, taken from here

    #!/bin/sh
    
    sudo apt-get install -y openssl build-essential xorg libssl-dev
    wget http://download.gna.org/wkhtmltopdf/0.12/0.12.3/wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
    tar -xJf wkhtmltox-0.12.3_linux-generic-amd64.tar.xz
    cd wkhtmltox
    sudo chown root:root bin/wkhtmltopdf
    sudo cp -r * /usr/
    
  2. Added this CSS (as suggested in one of the answers here):

    tr, td div, th div{
        page-break-inside: avoid;
    }
    
  3. And then also add <thead> and <tbody> tags as suggested here as well (without these the table would still break in an ugly way):

    <table>
    	<thead>
    	    <tr>
    		    <th>Column 1</th>
    			<th>Column 2</th>
    		</tr>
    	</thead>
    
    	<tbody>
    		<tr>
    			<td>Value 1</td>
    			<td>Value 2</td>
    		</tr>
    	</tbody>
    </table>
    

With these modifications I can now successfully use Mako templates to generate the HTML and then feed that to Wkhtmltopdf and get a beautifully paginated PDF.

Solution 6 - Wkhtmltopdf

I tried all manner of manipulations to my tables, but nothing I tried could stop the page breaks being put into the middle of a row. In desperation I tried different versions, and found the following:

Wkhtmltopdf 0.12.2.1: Bad

Wkhtmltopdf 0.12.3: Bad

Wkhtmltopdf 0.12.1: Good

My solution was to downgrade to version 0.12.1, which solved my issues. Granted, they might have been partly due to not being super OCD about my html, but as the HTML is generated inside TinyMCE (by users) I don't really have much choice.

Also, nested tables don't work in any version for me.

Solution 7 - Wkhtmltopdf

I was facing the same issue add after a lot of trial n errors this css solved the issue

tr {
    display: inline-table;
}

Solution 8 - Wkhtmltopdf

How to use page breaks inside pdf without break a tr?

Here is solution that you can use in any html file.....

After start your tr you have to take a div inside the tr and give this css to the div:

<tr>
      <div style="page-break-inside:avoid !important; page-break-after:auto !important; overflow: hidden; display:block !important; width:100% ">
     </tr>

Solution 9 - Wkhtmltopdf

I solved the issue using a combination of some suggested solutions.

I wrapped my table in a div and defined the following CSS.

.wrapping-div {
        display: block;
        page-break-inside: avoid !important;
    }

.wrapping-div table, .wrapping-div tbody, .wrapping-div tr, .wrapping-div td, .wrapping-div th {
        page-break-inside: avoid !important;
    }

The table structure when finished was defined as the following example:

<div class="wrapping-div">
 <table>
  <tbody>
   <tr>
    <th>
      header
    </th>
    <td>
      content
    </td>
   </tr>
  </tbody>
 </table>
</div>

I didn't need to create any div inside the td or th tags.

Important things that I noticed while trying to solve the problem:

  • The tbody must be included in the table
  • The div must have display: block
  • When a table doesn't fit in a page, it will automatically move the whole table to the next page (I haven't tried this one with huge tables)
  • If you remove only the ".wrapping-div table" selector from the CSS, it will allow the table to be split in two pages, but will render it correctly, not breaking one cell in two pages (it's like the default behavior on Word)

I hope this helps.

Solution 10 - Wkhtmltopdf

With the addition to what Nanotelep says, here is the working implementation of manual table page breaking algorithm. https://github.com/AAverin/JSUtils/tree/master/wkhtmltopdfTableSplitHack

Solution 11 - Wkhtmltopdf

The answers above did not work to me. I had to specifically disable the zoom option my pdfkit config.

PDFKit.configure do |config|

  config.default_options = {
    print_media_type: false,
    page_size: "A4",
    encoding: "UTF-8",
    ## Make sure the zoom option is not enabled!
    ## zoom: '1.3',
    disable_smart_shrinking: false,
    footer_right: "Page [page] of [toPage]"
  }

end

Solution 12 - Wkhtmltopdf

For anyone still having problems with this, one thing to remember is that the table has to be a direct child of body, otherwise the css won't work (at least that's what happened with me).

Solution 13 - Wkhtmltopdf

I found this ridiculous solution, but it's worked very well for me :)

I just put a very long rowspan column like this

<td rowspan="XXX TOTAL ROWS" style="width:0px"></td>

and then the table would not break.

Solution 14 - Wkhtmltopdf

Another option: place each tr in its own tbody and then apply the peage break css rules to the tbody. Tables support multiple tbodys.

A bit of extra markup, but works decently for me.

Solution 15 - Wkhtmltopdf

I have struggled a lot with the issue, using latest h4cc/wkhtmltopdf-amd64 version 0.12.4 and finally made it working by downgrading the version of the package to 0.12.3!

Solution 16 - Wkhtmltopdf

To avoid page break, We can use page break avoid css option.

tr { page-break-inside: avoid; }

Break any content (Image/ Text) and make it appear in the next page

.sample-image { page-break-before: always; }

Solution 17 - Wkhtmltopdf

Do you have a table head? and a table body?

<table>
<tbody>
<tr><th>Name</th><th>Value</th></tr>
<tr><td>url</td><td>stackoverflow.com</td></tr>
<tr><td>ip</td><td>123.123.123.123</td></tr>
</tbody>
</table>

That is the proper formatting of a table, while most browsers couldn't care less, converters like the one you mention can, if your missing <tbody> or <th> tags i suggest you try adding those first.

Solution 18 - Wkhtmltopdf

Add this CSS with respective classes

#main_div {
        position: relative;
        width: 672px; /* find your width in px based on the page margins */
    }
tr td {
        page-break-before: auto;
        page-break-inside: avoid !important;
    }

But the most important is to give to your container which contains the table (or some parent div) a fixed width in pixels. Should work for most (WebKit) pdf generators and permit them to calculate correctly the heights.

I can confirm that works for me with wkhtmltopdf 0.12.6 (with patched qt) in kubuntu 20.04

Solution 19 - Wkhtmltopdf

I do not understand why the most correct version is not yet here ;)

If you have a fixed layout, there is an actual pretty easy way to do this. You make the layout fixed (table-layout: fixed at the table), set the sizes with the first row or a colgroup:

      <colgroup>
        <col style="width: 5%">
        <col style="width: 35%">
        <col style="width: 20%">
        <col style="width: 20%">
        <col style="width: 20%">
      </colgroup>

and then you do this for each table.

so you create

    <table>
     <colgroup> [...] </colgroup>
     <tbody>
      <tr> [...] </tr>
     </tbody>
    </table>

And how do you avoid the page break now? Simple, you add a surrounding <div class='page-breaker'> around each table with the css

    .page-breaker {
      page-break-inside: avoid;
      page-break-before: avoid;
    }

So each Table has the same column widths and if needed, a tgroup gets a page break before.

With this solution, the display: block does not break the styling of the table.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
QuestionMohammad Sadiq ShaikhView Question on Stackoverflow
Solution 1 - WkhtmltopdfJoel PeltonenView Answer on Stackoverflow
Solution 2 - WkhtmltopdfInternal Server ErrorView Answer on Stackoverflow
Solution 3 - WkhtmltopdfNacho MoçoView Answer on Stackoverflow
Solution 4 - WkhtmltopdfUnixAgainView Answer on Stackoverflow
Solution 5 - WkhtmltopdfAcapulcoView Answer on Stackoverflow
Solution 6 - WkhtmltopdfBen HitchcockView Answer on Stackoverflow
Solution 7 - Wkhtmltopdfakhilesh.saipangalluView Answer on Stackoverflow
Solution 8 - WkhtmltopdfVibha KachhelaView Answer on Stackoverflow
Solution 9 - WkhtmltopdfTiago FreitasView Answer on Stackoverflow
Solution 10 - WkhtmltopdfAAverinView Answer on Stackoverflow
Solution 11 - WkhtmltopdfHendrikView Answer on Stackoverflow
Solution 12 - WkhtmltopdfLuccas CorreaView Answer on Stackoverflow
Solution 13 - WkhtmltopdfaswzenView Answer on Stackoverflow
Solution 14 - WkhtmltopdfTroy MorehouseView Answer on Stackoverflow
Solution 15 - WkhtmltopdfemixView Answer on Stackoverflow
Solution 16 - WkhtmltopdfArvind singhView Answer on Stackoverflow
Solution 17 - Wkhtmltopdfsuicidal.bananaView Answer on Stackoverflow
Solution 18 - WkhtmltopdfAssyKView Answer on Stackoverflow
Solution 19 - WkhtmltopdfNukeyView Answer on Stackoverflow