如何应用CSS分页符打印有大量行数的表格?

100

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

11个回答

171

您可以使用以下代码:

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

请查阅W3C的CSS打印规范以获取更多详细信息。

同时,请参考Salesforce开发者论坛


9
如果您正在使用诸如Bootstrap之类的框架,请注意使用类似于.spanX(使用float样式)的东西可能会破坏页面断点属性,我自己也因这个小细节浪费了很多时间。 - jaredsmith
1
这个适用于UIWebView,所以我认为现在它也适用于Safari。 - JonEasy
David感谢你分享能够在Safari或Chrome上使用的解决方案。 JonEasy如果这个解决方案无法在Safari上工作,你可以使用David的解决方案。 @Maxence很高兴它有帮助。 抱歉我有几个月没活跃了,所以不能及时回复。 - Hemant Metalia
2
这个解决方案不能在单元格的边框之间干净地打断多行单元格,但会在中间打断它们。不过我已经找到了一个解决方案,在所有当前的浏览器中(Safari、FF 和 Chrome)都有效:https://dev59.com/xafja4cB1Zd3GeqPpQjt#47498775 - Thomas Tempelmann
1
@Saif 这个答案是几年前提供的,可能不符合较新版本的浏览器。但你可能会从中得到一些提示。 - Hemant Metalia
显示剩余5条评论

25

在想要应用页面分隔符的位置,无论是 table 还是 tr,都需要添加一个类例如 page-break,并使用以下 CSS:

/* 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">

并且它将按照您的要求工作

或者,您也可以使用相同的div结构:

CSS:

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

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

分割线:

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

19
只有在预先知道每页可以容纳多少行的情况下,此方法才有效(因为您必须直接在标记中声明分页)。如果表格行中的数据可能换行到第二行,那么这可能很困难(甚至是不可能的)。而且,如果存在多个页面大小(A4与US Letter与US Legal),该怎么办? - aapierce
这个解决方案在使用多行单元格和多列时对我不起作用。不过,我找到了一个解决方法:https://dev59.com/xafja4cB1Zd3GeqPpQjt#47498775 - 它也解决了@aapierce提到的问题。 - Thomas Tempelmann
2
在Chrome v64中无法使tr打破。 - Avatar

16
我已经寻找了这个问题的解决方法。我有一个jquery mobile网站,有一个最终打印页面,它将几十个页面组合在一起。我尝试了上面提到的所有修复方法,但是我能做到的唯一一件事就是这个:

我已经寻找了这个问题的解决方法。我有一个jquery mobile网站,有一个最终打印页面,它将几十个页面组合在一起。我尝试了上面提到的所有修复方法,但是我能做到的唯一一件事就是这个:

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

如果将HTML代码放置在两个TR标签之间,这段代码可以在Chrome中正常工作,但在Firefox中无法正常工作。在Firefox中,可以使用CSS规则:table tr:nth-child(10) {page-break-after: always;page-break-inside: avoid;}。 - andrejs82

8

不幸的是,以上示例在Chrome浏览器中对我无效。

我想出了以下解决方案,您可以指定每个页面的最大高度(以像素为单位)。当行数达到该高度时,表格将被拆分成单独的表格。

$(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();

});

您还需要在样式表中添加以下内容。
    div.tablePage {
        page-break-inside:avoid; page-break-after:always;            
    }

当表格只有一行时,不执行任何操作。 - Chris

1
使用SelectPdf转换为PDF时,我无法让一组行保持在一起。尝试将它们放入<div style="break-inside: avoid;">中,但没有效果。直到我发现这个链接:https://dev59.com/t2ox5IYBdhLWcg3wTypx#27209406,重新思考了我的逻辑,并将不想拆分的内容放在<tbody>中。请注意保留HTML标签。
<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>

这将导致一个包含多个<tbody>的表格,但这是完全可以接受的,因为许多人使用这种精确模式来组合行。

1
这对我有效:

这是适用于我的情况:

<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>

来自这个帖子:避免表格行内分页


这个有点有效。意思是它不会完全切断底部的行数据,虽然仍然会切断一些行,但至少比实际问题好了一些。 - Avinash Dalvi

0

我最终意识到,我的大量内容溢出了表格并且无法正确分页,其实根本不需要放在表格中。

虽然这不是一个技术性的解决方案,但当我不再需要表格时,结束表格并开始新的表格来制作页脚,这解决了我的问题。

希望能对某些人有所帮助...祝好运!


0
如果你知道每页要显示多少个项目,你可以这样做。它将在每20个项目后开始一个新页面。
.row-item:nth-child(20n) {
    page-break-after: always;
    page-break-inside: avoid;
}

那对我不起作用 :( 我正在使用 CHROME 83.0.4103.116 - andrejs82

-1

我们尝试了这里和其他地方提到的许多不同的解决方案,但都没有为我们工作。然而,最终我们找到了一个对我们有效的解决方案,对我们来说似乎是一个 Angular 问题。我不明白为什么这样做有效,但对我们来说确实有效,最终我们不需要任何页面分页的 CSS。

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

希望这能帮助到其他人,因为我们花了几天时间来解决这个问题。


-1
这是一个例子:
通过css:
<style>
  .my-table {
    page-break-before: always;
    page-break-after: always;
  }
  .my-table tr {
    page-break-inside: avoid;
  }
</style>

或者直接在元素上:

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

这个成功地使用了4页来实现一个实际上只有2页的表格,看起来在Safari(6)和Chrome(24)中与没有CSS的效果相同。 - David

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接