How to deal with page breaks when printing a large HTML table
我有一个项目,要求打印带有许多行的HTML表格。
我的问题是表格在多页上的打印方式。 有时它将切成两行,使其变得不可读,因为一半在页面的边缘,其余部分打印在下一页的顶部。
我能想到的唯一可行的解决方案是使用堆叠的DIV而不是表格,并在需要时强制分页符..但是在进行整个更改之前,我想我可以在这里问一下。
-
在切线上,可能值得在表中添加一个
和以下css thead {display: table-header-group; } ,以便在所有后续页面上打印表头(对于loooooong数据表很有用)。
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>- 并非在所有浏览器中都适用。它似乎确实可以在FireFox 3.6 Mac OS中工作。
- 不幸的是,它似乎在W4的FF4中不起作用
- 在WebKit浏览器(例如Safari和Chrome)中,此操作也会失败
- 只有thead {display:table-header-group} css条目在最新的FF12中有效,而在Chrome 18+中均不起作用...
- 尽管这是符合标准的方法,但是当前唯一实现该标准的浏览器是Opera。请注意,这是css2的一部分,因此缺少实现可能会在一段时间内成为问题,因为显然没有人在乎。
- CSS 2.1规范指示分页符样式属性仅应用于块级元素。表格行的默认显示模式是表格行。不幸的是,默认情况下,没有任何表元素是块级元素,包括表本身。
- @lthibodeaux我看到了……"用户代理必须在根元素的正常流程中将这些属性应用于块级元素。用户代理还可以将这些属性应用于其他元素,例如表行元素。" (强调我的)。
- @Sinannr这不是必须的,因此您不能依靠它,不幸的是,从我的测试中,我可以看到Webkit看到了"可能"而忽略了它之外的任何内容。奇怪的是,IE获得了一些相当不错的大表打印支持。从来没有想过在任何给定的观点上赞美它。
-
@lthibodeaux我在消息的开头就假定了"我看到了",并且粗体可能表明我意识到我不能依靠它。 Safari的问题似乎不在于分页,而在于
display:table-header-group 和display:table-footer-group 似乎没有效果的事实,我认为这是合理且直观的。 - 并非在所有浏览器中都适用。
- 我可以确认它在最新的Chrome和Safari版本中可以正常运行。
- 我可以确认这不能在Chrome或任何其他Webkit浏览器(例如Safari,Opera)中正常工作-除非"正常工作"是指"排除任何被视为可选的功能"。我认为大多数人想要的是运行页眉和页脚以及仅允许在行之间进行分页的表,而自2015/11/13起,这两种方法均未在Webkit中实现。
- @DoctorDestructo我认为是一个错误报告。
- @Sinannr:我刚刚尝试了您的解决方案,页脚未按预期工作:stackoverflow.com/questions/38027411/
- @MiskateErorr您的陈述是错误的。您问题中显示的HTML可以正常工作。您还有其他问题。提出一个仍然有问题的最小案例,然后更新您的问题。
- 可以确认,这将使在chrome 51中的大表的打印更加稳定。
注意:当使用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>- 在Chrome上对我有效,并且是一个不错的普通CSS解决方案。
- 我正在尝试相同的解决方案,但它不会破坏表数据并消失多余的数据,而不是在下一页显示它。有什么猜想吗?
从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 ,它可以工作,但会弄乱表的布局。-
这是使用jquery动态添加div的简单方法:
$(document).ready(function(){$("table tbody th, table tbody td").wrapInner("");}); - 感谢sinan rn,vicenteherrera和Chrisbloom7。我应用了您的答案组合,现在可以使用了!
-
您可以尝试将@media CSS设置为
tr { display: block; } (仅用于打印),而不是添加所有多余的元素。 (Havent经过测试,但值得一看)
在Chrome中,这里没有答案对我有用。 GitHub上的AAverin为此目的创建了一些有用的Javascript,并且对我有用:
只需将js添加到您的代码中,然后将" splitForPrint"类添加到表中,它将整洁地将表拆分为多个页面,并将表标题添加到每个页面。
-
您是否有关于如何应用此方法的示例?我一直试图将我的表className分配为
splitForPrint ,但是在JS中,没有地方使用classNamesplitForPrint 来引用元素。只有var splitClassName = splitForPrint; 所在的部分,仅此而已。 - 投反对票的原因是,如果不进行大量挑选和重新配置,您链接到的脚本就不能解决OP问题,并且您没有提供任何示例说明如何进行操作。
- 在Mac上的Chrome v39上不起作用
- 对我而言,这就像是一种魅力,其他解决方案均无效。 +1必须添加一点CSS才能获得正确的中断。page-break {page-break-after:总是; }
- 是的,通过添加.page-break {page-break-after:always; }它挽救了我的生命!
使用以下CSS属性:
1
2
3page-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>通过
- 我不确定,您必须检查一下。如果不是,请拆分为不同的数组,并以空div分隔这些数组
- (或在"表格"元素上)
- 我认为,您必须将其应用于表行甚至单元格,而不是应用于表。除此之外,它应该工作。
- 在chrome中不起作用。应用于TR时将被忽略,就像6/13/2012
我最近通过一个好的解决方案解决了这个问题。
CSS:
1
2
3
4.avoidBreak {
border: 2px solid;
page-break-inside:avoid;
}JS:
1
2
3
4
5function Print(){
$(".tableToPrint td, .tableToPrint th").each(function(){ $(this).css("width", $(this).width() +"px") });
$(".tableToPrint tr").wrap("");
window.print();
}奇迹般有效!
我最终遵循@vicenteherrera的方法,做了一些调整(可能是Bootstrap 3特有的)。
基本上;我们不能破坏
TR 或td ,因为它们不是块级元素。因此,我们将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
3html {
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
11TFOOT.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
6tr
{
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;
}这并不能防止行中断。每个单元格的内容。
Copyright © 码农家园 联系:[email protected]