打印大型HTML表格时如何处理分页符


261

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

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

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


28
在切线上,可能需要<thead>使用以下CSS 将a添加到您的表中,thead {display: table-header-group; }以便在所有后续页面上打印表头(适用于loooooong数据表)。
大卫说,请

Answers:


277
<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<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>

18
这在WebKit浏览器(例如Safari和Chrome)中也失败
Michael Haren 2012年

5
尽管这是符合标准的方法,但当前唯一实现该标准的浏览器是Opera。请注意,这是css2的一部分,因此在不久的将来,缺少实现可能会成为一个问题,因为显然没有人关心。
2012年

16
CSS 2.1规范指示分页符样式属性仅应用于块级元素。表格行的默认显示模式是表格行。不幸的是,默认情况下,没有任何表元素是块级元素,包括表本身。
lsuarez 2012年

2
@SinanÜnür这不是必须的,因此您不能依赖它,不幸的是,从我的测试中,我可以看到webkit看到了“可能”,而忽略了它之外的任何内容。奇怪的是,IE浏览器有一些不错的大表打印支持。没想到我会在任何给定的观点上赞美它。
lsuarez

6
我可以确认这在Chrome或任何其他Webkit浏览器(例如Safari,Opera)中都无法正常工作-除非“正常工作”是指“排除任何被认为是可选的功能”。我认为大多数人想要的是运行页眉和页脚以及仅允许在行之间进行分页的表,而自2015/11/13起,这两种方法均未在Webkit中实现。
DoctorDestructo

47

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

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

在Chrome上对我有效,并且是一个不错的普通CSS解决方案。
瑞安

1
我正在尝试相同的解决方案,但它不会破坏表数据并消失多余的数据,而不是将其显示在下一页上。有什么猜想吗?
空指针

24

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

<!DOCTYPE HTML>
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=UTF-8">
<title>Test</title>
<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><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <tr>
            <td><div>Long<br />cell<br />should'nt<br />be<br />cut</div></td>
        </tr>
        <!-- 500 more rows -->
        <tr>
            <td>x</td>
        </tr>
    </tbody>
    </table>
</body>
</html>

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

如果您尝试display:blockTR代码,并使用那里page-break-inside:avoid,它的工作原理,但周围混乱与表格的布局。


2
这是一种使用jquery动态添加div的简单方法:$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("<div></div>");});
Chris Bloom 2014年

1
感谢sinanürün,vicenteherrera和Chrisbloom7。我应用了您的答案组合,现在可以使用了!
Nurhak Kaya

您可以尝试将@media CSS设置tr { display: block; }为“仅打印”,而不是添加所有无关的<div>元素。(尚未测试,但值得一看)
Stephen R

11

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

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


您是否有关于如何应用此方法的示例?我一直试图将我的表className分配为,splitForPrint但是在JS中,没有地方使用className来引用元素splitForPrint。只有一部分,var splitClassName = 'splitForPrint';但仅此而已。
Compaq LE2202x

投反对票的原因是,如果不进行大量的选择和重新配置,链接到的脚本无法解决OP的问题,并且您未提供任何示例说明如何进行操作。
克里斯·布鲁姆

对我来说,这就像是一种魅力,其他解决方案都没有。+1必须添加一点CSS才能获得正确的中断。page-break {page-break-after:总是; }
fhugas '16

是的,添加.page-break {page-break-after:总是; }它挽救了我的生命!
milodky '16

7

使用以下CSS属性:

page-break-after

page-break-before 

例如:

<html>
<head>
<style>
@media print
{
table {page-break-after:always}
}
</style>
</head>

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

通过


我不确定,您必须检查一下。如果不是,请分割成不同的数组,并用一个空的div分隔这些数组
marcgg

我认为,您将不得不将其应用于表格行甚至单元格,而不是应用于表格。除此之外,它应该工作。
Pekka

2
在Chrome中不起作用。当应用于TR
ladieu 2012年

5

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

CSS

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

JS

function Print(){
    $(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width",  $(this).width() + "px")  });
    $(".tableToPrint tr").wrap("<div class='avoidBreak'></div>");
    window.print();
}

奇迹般有效!


2

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

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

<style>
    @media print {
        /* avoid cutting tr's in half */
        th div, td div {
            margin-top:-8px;
            padding-top:8px;
            page-break-inside:avoid;
        }
    }
</style>
<script>
    $(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("<div></div>");
    })
</script>

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


1

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

html {
height: 0;
}

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

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

希望这也对您有用。


0

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

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

带有样式的tfoot:position: fixed; bottom: 0px; 位于最后一页的底部,但是如果页脚过高,则会与表格内容重叠。

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

让我们放两脚:

TFOOT.placer {
  display: table-footer-group;
  height: 130px;
}

TFOOT.contenter {
  display: table-footer-group;
  position: fixed;
  bottom: 0px;	
  height: 130px;
}
<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

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

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

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


-2

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

的HTML

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

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


-3

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

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

html结构为:

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

在我的情况下,还有其他问题thead tr,但这解决了原来的问题,即保持表行不中断。

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

#theTable td *
{
  page-break-inside:avoid;
}

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

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.