我以编程方式生成html,以便为打印提供良好的渲染效果。
我必须打印可能跨越多个页面的表格。这带来了一些挑战,例如阻止细胞内容分布在两页上,如下所示:
我在this answer中找到了一个使用page-break-inside:avoid
的解决方案,以及this answer,display: block
使用了<tr>
来阻止它们从垂直分裂。
但是,这也会导致行不再相互垂直对齐。我该如何解决这个问题?
以下是它的外观(以及浏览器如何在屏幕上呈现):
以下是打印的内容:
如何使打印输出对齐,与屏幕上的对齐方式相同,而不必失去display: block
在分页符处保持单元格垂直完整的能力?它必须在macOS上的Webkit(Safari)中工作。
这里是完整的HTML代码。它跨越两页,以便人们可以检查单个单元格是否出现在下一页的一半和一半(这是不希望的):
<!DOCTYPE html><html><head><meta charset="utf-8"><style type="text/css">
th, td { border: 1px solid #aaa; }
@media print {
table, tr, td, th {
page-break-inside: avoid;
}
tr {
display: block;
page-break-before: auto;
}
}
</style></head>
<body>
<table style="width:40%">
<tr><th>A</th><th>B</th><th>C</th></tr>
<tr><td>more text<br>1<br>2<br>3<br>4<br>5<br></td><td>more text</td><td>more text</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
</table>
</body></html>
更新
我还尝试使用div
代替table
的{{3}}。这在打印时会产生略微不同的结果,但仍然很糟糕(现在单元格高度也是错误的):
答案 0 :(得分:1)
添加
td, th {
width: 10000px;
}
在@media print { }
内完成了使示例代码有效的技巧。
现在打印的列再次正确对齐,每行都停留在一个页面上,从不跨越两页。
适用于当前版本的Webkit(Safari),FF和Chrome(仅在macOS上进行测试)。
<强>警告:强>
不幸的是,以上并非万无一失。它仅适用于此示例,因为每行中的单元格具有相同的宽度。
一旦这些宽度是随机的,像10000px这样的过度像素宽度会再次弄乱列。
我发现的唯一解决方案是提供要使用的实际宽度。由于这是用于打印,并且因为我知道我想要打印成特定的纸张格式(例如DIN A4或US Letter),所以我可以准确地指定列宽。
因此,虽然此解决方案对于屏幕上的浏览器中的网页视图来说不是一个好的解决方案,但总宽度可能会有所不同,只要可以预测目标打印尺寸,这对于打印来说是一个很好的解决方案。
以下是完整的html代码,将列宽设置为4cm,2cm和3cm:
<!DOCTYPE html><html><head><meta charset="utf-8"><style type="text/css">
th, td { border: 1px solid #aaa; }
@media print {
table, tr, td, th {
page-break-inside: avoid;
}
tr {
display: block;
page-break-before: auto;
}
td:nth-child(1), th:nth-child(1) {
width: 4cm;
}
td:nth-child(2), th:nth-child(2) {
width: 2cm;
}
td:nth-child(3), th:nth-child(3) {
width: 3cm;
}
}
</style></head>
<body>
<table>
<tr><th>A</th><th>B</th><th>C</th></tr>
<tr><td>more text<br>1<br>2<br>3<br>4<br>5<br></td><td>more text</td><td>more text</td></tr>
<tr><td>1 adasd<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1asd<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>xsdsdfsf</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2 asda asdas<br>3<br>4<br>5<br>6<br></td><td>xasdada</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4 asdasd <br>5<br>6<br></td><td>x</td><td>x</td></tr>
</table>
</body></html>
答案 1 :(得分:1)
不依赖于固定列宽的此问题的另一种解决方案是将每个单元格的内容包装在display:block
元素中,并将其设置为page-break-inside: avoid
。如果您不想首先更改HTML,则可以在加载时动态更改DOM。我很懒,在以下示例中使用的是jQuery:
<!DOCTYPE html><html><head><meta charset="utf-8"><style type="text/css">
th, td { border: 1px solid #aaa; }
@media print {
td hack {
display: block;
page-break-inside: avoid;
}
}
</style>
<script src="https://code.jquery.com/jquery-3.5.0.js"></script>
<script>
window.addEventListener('load', function() {
$( "td" ).wrapInner( "<hack></hack>" );
})
</script>
</head>
<body>
<table>
<tr><th>A</th><th>B</th><th>C</th></tr>
<tr><td>more text<br>1<br>2<br>3<br>4<br>5<br></td><td>more text</td><td>more text</td></tr>
<tr><td>1 adasd<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1asd<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>xsdsdfsf</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4<br>5<br>6<br></td><td>x</td><td>x</td></tr>
<tr><td>1<br>2 asda asdas<br>3<br>4<br>5<br>6<br></td><td>xasdada</td><td>x</td></tr>
<tr><td>1<br>2<br>3<br>4 asdasd <br>5<br>6<br></td><td>x</td><td>x</td></tr>
</table>
</body></html>
结果看起来会有些不同:
您看到以下问题:
但是该解决方案确实适用于WebKit浏览器,并且仍呈现为普通表。