关于CSS:打印大型HTML表格时如何处理分页符

How to deal with page breaks when printing a large HTML table

我有一个项目,要求打印带有许多行的HTML表格。

我的问题是表格在多页上的打印方式。 有时它将切成两行,使其变得不可读,因为一半在页面的边缘,其余部分打印在下一页的顶部。

我能想到的唯一可行的解决方案是使用堆叠的DIV而不是表格,并在需要时强制分页符..但是在进行整个更改之前,我想我可以在这里问一下。


1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Test
<style type="text/css">
    table { page-break-inside:auto }
    tr    { page-break-inside:avoid; page-break-after:auto }
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tbody>
        <tr>
            <td>x</td>
        </tr>
        <tr>
            <td>x</td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>


注意:当使用page-break-after:always作为标记时,它将在表的最后一位之后创建一个分页符,每次都在末尾创建一个完全空白的页面!
要解决此问题,只需将其更改为page-break-after:auto。
它将正确中断,并且不会创建额外的空白页。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
<html>
<head>
<style>
@media print
{
  table { page-break-after:auto }
  tr    { page-break-inside:avoid; page-break-after:auto }
  td    { page-break-inside:avoid; page-break-after:auto }
  thead { display:table-header-group }
  tfoot { display:table-footer-group }
}
</style>
</head>

<body>
....
</body>
</html>


从Sinanünür解决方案扩展:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
Test
<style type="text/css">
    table { page-break-inside:auto }
    div   { page-break-inside:avoid; } /* This is the key */
    thead { display:table-header-group }
    tfoot { display:table-footer-group }
</style>
</head>
<body>
    <table>
        <thead>
            <tr><th>heading</th></tr>
        </thead>
        <tfoot>
            <tr><td>notes</td></tr>
        </tfoot>
        <tr>
            <td>Long<br />cell<br />should'nt<br />be<br />cut</td>
        </tr>
        <tr>
            <td>Long<br />cell<br />should'
nt<br />be<br />cut</td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

似乎在某些浏览器中,page-break-inside:avoid仅考虑了块元素,而不考虑单元格,表,行或内联块。

如果尝试display:block TR标记并在其中使用page-break-inside:avoid,它可以工作,但会弄乱表的布局。


在Chrome中,这里没有答案对我有用。 GitHub上的AAverin为此目的创建了一些有用的Javascript,并且对我有用:

只需将js添加到您的代码中,然后将" splitForPrint"类添加到表中,它将整洁地将表拆分为多个页面,并将表标题添加到每个页面。


使用以下CSS属性:

1
2
3
page-break-after

page-break-before

例如:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
<html>
<head>
<style>
@media print
{
table {page-break-after:always}
}
</style>
</head>

<body>
....
</body>
</html>

通过


我最近通过一个好的解决方案解决了这个问题。

CSS:

1
2
3
4
.avoidBreak {
    border: 2px solid;
    page-break-inside:avoid;
}

JS:

1
2
3
4
5
function Print(){
    $(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width",  $(this).width() +"px")  });
    $(".tableToPrint tr").wrap("");
    window.print();
}

奇迹般有效!


我最终遵循@vicenteherrera的方法,做了一些调整(可能是Bootstrap 3特有的)。

基本上;我们不能破坏TRtd,因为它们不是块级元素。因此,我们将div嵌入到每个中,并对div应用我们的page-break-*规则。其次;我们在每个div的顶部添加一些填充,以补偿任何样式瑕疵。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
<style>
    @media print {
        /* avoid cutting tr's in half */
        th div, td div {
            margin-top:-8px;
            padding-top:8px;
            page-break-inside:avoid;
        }
    }
</style>

    $(document).ready(function(){
        // Wrap each tr and td's content within a div
        // (todo: add logic so we only do this when printing)
        $("table tbody th, table tbody td").wrapInner("");
    })

为了抵消某种引入的抖动(据我的猜测-自举),必须对边距和填充进行调整。我不确定是否要从该问题的其他答案中提出任何新的解决方案,但是我认为这可能会对某人有所帮助。


我遇到了同样的问题,到处寻找解决方案,最后,我找到了适用于所有浏览器的东西。

1
2
3
html {
height: 0;
}

使用此CSS或代替CSS,您可以使用此javascript

1
$("html").height(0);

希望这也对您有用。


我检查了许多解决方案,但任何人都做得不好。

所以我尝试了一个小把戏,它起作用了:

风格:position: fixed; bottom: 0px;
放在最后一页的底部,但是如果页脚太高,则会与表的内容重叠。

只用:display: table-footer-group;
没有重叠,但不在最后一页的底部...

让我们放两脚:

1
2
3
4
5
6
7
8
9
10
11
TFOOT.placer {
  display: table-footer-group;
  height: 130px;
}

TFOOT.contenter {
  display: table-footer-group;
  position: fixed;
  bottom: 0px; 
  height: 130px;
}
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
<TFOOT  class='placer'>
  <TR>
    <TD>
      <!--  empty here
-->
    </TD>
  </TR>
</TFOOT>   
<TFOOT  class='contenter'>
  <TR>
    <TD>
      your long text or high image here
    </TD>
  </TR>
</TFOOT>

一个保留在非末页上,第二个保留在您的页脚中。


我尝试了上面给出的所有建议,并找到了解决此问题的简单且有效的跨浏览器解决方案。此解决方案不需要样式或分页符。对于解决方案,表的格式应类似于:

1
2
3
4
5
6
7
8
9
10
11
<table>
    <thead>  <!-- there should be <thead> tag-->
        <td>Heading</td> <!--//inside <thead> should be <td> it should not be <th>-->
    </thead>
    <tbody><!---<tbody>also must-->
        <tr>
            <td>data</td>
        </tr>
        <!--100 more rows-->
    </tbody>
</table>

以上格式经过测试,可在跨浏览器中使用


大家好...这里的大多数解决方案都没有用。这就是我的工作方式。

的HTML

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<table>
  <thead>
   <tr>
     <th style="border:none;height:26px;"></th>
     <th style="border:none;height:26px;"></th>
     .
     .
   </tr>
   <tr>
     <th style="border:1px solid black">ABC</th>
     <th style="border:1px solid black">ABC</th>
     .
     .
   <tr>
  </thead>
<tbody>

    //YOUR CODE

</tbody>
</table>

第一组头部用作虚拟头部,这样在分页符中断时第二个头部(即原始头部)不会缺少顶部边框。


接受的答案并非在所有浏览器中都对我有用,但是跟随css却对我有用:

1
2
3
4
5
6
tr    
{
  display: table-row-group;
  page-break-inside:avoid;
  page-break-after:auto;
}

html结构为:

1
2
3
4
5
6
7
8
9
10
<table>
  <thead>
    <tr></tr>
  </thead>
  <tbody>
    <tr></tr>
    <tr></tr>
    ...
  </tbody>
</table>

就我而言,thead tr还有一些其他问题,但这解决了原来的问题,即保持表行不被破坏。

由于标题问题,我最终得到了:

1
2
3
4
#theTable td *
{
  page-break-inside:avoid;
}

这并不能防止行中断。每个单元格的内容。