如何应用 CSS 分页打印一个有很多行的表?

我有一个动态表在我的网页,有时包含很多行。我知道有 page-break-beforepage-break-after CSS 属性。 如果需要的话,我应该把它们放在代码的哪个位置,以便强制打开页面?

263164 次浏览

You can use the following:

<style type="text/css">
table { page-break-inside:auto }
tr    { page-break-inside:avoid; page-break-after:auto }
</style>

Refer the W3C's CSS Print Profile specification for details.

And also refer the Salesforce developer forums.

Here is an example:

Via css:

<style>
.my-table {
page-break-before: always;
page-break-after: always;
}
.my-table tr {
page-break-inside: avoid;
}
</style>

or directly on the element:

<table style="page-break-before: always; page-break-after: always;">
<tr style="page-break-inside: avoid;">
..
</tr>
</table>

Wherever you want to apply a break, either a table or tr, you needs to give a class for ex. page-break with CSS as mentioned below:

/* class works for table row */
table tr.page-break{
page-break-after:always
}


<tr class="page-break">


/* class works for table */
table.page-break{
page-break-after:always
}


<table class="page-break">

and it will work as you required

Alternatively, you can also have div structure for same:

CSS:

@media all {
.page-break  { display: none; }
}


@media print {
.page-break  { display: block; page-break-before: always; }
}

Div:

<div class="page-break"></div>

I have looked around for a fix for this. I have a jquery mobile site that has a final print page and it combines dozens of pages. I tried all the fixes above but the only thing I could get to work is this:

<div style="clear:both!important;"/></div>
<div style="page-break-after:always"></div>
<div style="clear:both!important;"/> </div>

Unfortunately the examples above didn't work for me in Chrome.

I came up with the below solution where you can specify the max height in PXs of each page. This will then splits the table into separate tables when the rows equal that height.

$(document).ready(function(){


var MaxHeight = 200;
var RunningHeight = 0;
var PageNo = 1;


$('table.splitForPrint>tbody>tr').each(function () {


if (RunningHeight + $(this).height() > MaxHeight) {
RunningHeight = 0;
PageNo += 1;
}


RunningHeight += $(this).height();


$(this).attr("data-page-no", PageNo);


});


for(i = 1; i <= PageNo; i++){


$('table.splitForPrint').parent().append("<div class='tablePage'><hr /><table id='Table" + i + "'><tbody></tbody></table><hr /></div>");


var rows = $('table tr[data-page-no="' + i + '"]');


$('#Table' + i).find("tbody").append(rows);
}
$('table.splitForPrint').remove();


});

You will also need the below in your stylesheet

    div.tablePage {
page-break-inside:avoid; page-break-after:always;
}

this is working for me:

<td>
<div class="avoid">
Cell content.
</div>
</td>
...
<style type="text/css">
.avoid {
page-break-inside: avoid !important;
margin: 4px 0 4px 0;  /* to keep the page break from cutting too close to the text in the div */
}
</style>

From this thread: avoid page break inside row of table

If you know about how many you want on a page, you could always do this. It will start a new page after every 20th item.

.row-item:nth-child(20n) {
page-break-after: always;
page-break-inside: avoid;
}

You should use

<tbody>
<tr>
first page content here
</tr>
<tr>
..
</tr>
</tbody>
<tbody>
next page content...
</tbody>

And CSS:

tbody { display: block; page-break-before: avoid; }
tbody { display: block; page-break-after: always; }

I eventually realised that my bulk content that was overflowing the table and not breaking properly simply didn't even need to be inside a table.

While it's not a technical solution, it solved my problem to simply end the table when I no longer needed a table; then started a new one for the footer.

Hope it helps someone... good luck!

When converting to PDF with SelectPdf I couldn't get a group of rows to stay together. Tried to put them in a <div style="break-inside: avoid;"> but that didn't work.

Nothing was working until I found this: https://stackoverflow.com/a/27209406/11747650
Which made me rethink my logic and place the things I didn't want to split inside a <tbody>.

<table>
<thead style="display: table-header-group;">
<tr>
<th></th>
</tr>
</thead>


-- Repeating content --
<tbody style="break-inside: avoid;">
-- First row from group --
<tr>
<td> Only shown once per group </td>
</tr>


-- Repeating rows --
<tr>
<td> Shown multiple times per group </td>
</tr>
</tbody>

This results in a table that has multiple <tbody> but that's something that is completely fine as many people use this exact pattern to group together rows.

We tried loads of different solutions mentioned here and elsewhere and nothing worked for us. However we eventually found a solution that worked for us and for us it seems to somehow be an Angular issue. I don't understand why this works, but for us it does and we didn't need any page break css in the end.

@media print {
ng-component {
float: left;
}
}

So just hoping this helps someone else as it took us days to fix.