abstract:
获取页面中所有的table元素,计算table元素前的所有dom元素的高度,如果超出了当前可视容器的高度,那么就进行分割操作。
reference:
Window:load 事件 - Web API 接口参考 | MDN
HTML DOM Element nextSibling 属性
Q:
我的问题是:我要做一个打印HTML页面功能,这个页面的表格是动态生成的,具有多个表格,现在面临的问题是,在第一页末尾无法放下这一整个表格,如何做到将这个表格分割为两部分,第一部分占满第一页剩余的空间,第二部分放在第二页去。
这个表格是动态生成的,我无法确定从第几行分割?
A:
如果表格是动态生成的,并且你无法确定从第几行进行分割,那么就需要在生成表格时根据页面的可视高度来进行分割。
你可以使用JavaScript来获取页面的可视高度,并在生成表格时判断每个表格所占高度。当表格的高度超过页面可视高度时,就将剩余部分放在下一页打印。
<!DOCTYPE html>
<html>
<head>
<style>
@media print {
table {
display: block;
page-break-inside: avoid;
width: 100%;
}
.break {
page-break-before: always;
}
}
</style>
</head>
<body>
<script>
window.addEventListener('load', function() {
// 获取页面可视高度
var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// 获取所有表格
var tables = document.querySelectorAll('table');
// 循环遍历每个表格
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// 获取表格高度
var tableHeight = table.offsetHeight;
// 如果表格高度超过页面可视高度
if (tableHeight > pageHeight) {
// 创建一个新的分页元素
var breakElement = document.createElement('div');
breakElement.classList.add('break');
// 将剩余部分的表格插入到新分页元素中
while (table.nextSibling) {
breakElement.appendChild(table.nextSibling);
}
// 在当前表格之后插入新分页元素
table.parentNode.insertBefore(breakElement, table.nextSibling);
// 跳出循环,结束分割表格
break;
}
}
});
</script>
<!-- 动态生成的表格 -->
<table>
<!-- 表格内容 -->
</table>
</body>
</html>
Q:
你的方法是有效的,但是需要做出一些调整,
var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
你直接获取了整个可视高度,但是这个表格之前的元素你忘记考虑了. 并且 “计算表格之前元素的高度” 不是指表格上半部分的高度,而是指表格之前其他dom元素的高度
A:
你是希望计算表格之前其他 DOM 元素的高度,而不仅仅是表格上半部分的高度。
以下是经过修改的代码,以考虑表格之前其他 DOM 元素的高度:
<!DOCTYPE html>
<html>
<head>
<style>
@media print {
table {
display: block;
page-break-inside: avoid;
width: 100%;
}
.break {
page-break-before: always;
}
}
</style>
</head>
<body>
<script>
window.addEventListener('load', function() {
// 计算可视高度
var pageHeight = window.innerHeight || document.documentElement.clientHeight || document.body.clientHeight;
// 获取所有表格
var tables = document.querySelectorAll('table');
// 循环遍历每个表格
for (var i = 0; i < tables.length; i++) {
var table = tables[i];
// 计算表格之前元素的总高度
var heightBeforeTable = 0;
var prevElement = table.previousSibling;
while (prevElement) {
if (prevElement.offsetHeight) {
heightBeforeTable += prevElement.offsetHeight;
}
prevElement = prevElement.previousSibling;
}
// 计算表格高度
var tableHeight = table.offsetHeight;
// 如果表格高度加上之前元素高度超过页面可视高度
if ((tableHeight + heightBeforeTable) > pageHeight) {
// 创建新的分页元素
var breakElement = document.createElement('div');
breakElement.classList.add('break');
// 将表格插入到新分页元素中
breakElement.appendChild(table);
// 在当前表格之前插入新分页元素
table.parentNode.insertBefore(breakElement, table);
// 跳出循环,结束表格分割
break;
}
}
});
</script>
<!-- 动态生成的表格 -->
<table>
<!-- 表格内容 -->
</table>
</body>
</html>
现在,代码会将表格之前其他 DOM 元素的高度累加,并与表格高度一起比较来决定是否需要对表格进行分割。
Q:
你的答案是正确的,我现在有一个附加的需求,让所有的表格都自适应宽度。我的要求是,对于所有的table元素,我希望宽度自适应,并且里面的每个单元格都是平均分配宽度的
A:
<style>
table {
width: 100%;
border-collapse: collapse;
}
th, td {
padding: 8px;
text-align: left;
border: 1px solid #dddddd;
}
/* 让单元格自动分配宽度 */
td {
width: calc(100% / var(--columns));
}
</style>
Q:在页面上确实是平均分配了宽度,但是为什么打印时候没有这个效果?
A:在 CSS 中,通过 @media print
媒体查询可以设置打印样式,以及将其与屏幕样式分开。您可以在 @media print
媒体查询中重新设置表格的宽度和单元格的宽度,以确保在打印时也能保持相同的效果。
<style>
@media print {
table {
display: table; /* 将 display 属性修改为 table */
page-break-inside: avoid;
width: 100%;
}
.break {
page-break-before: always;
}
}
table {
width: 100%;
}
th,
td {
padding: 8px;
text-align: align;
border: 1px solid #754f4f;
}
/* 让单元格自动分配宽度 */
td {
width: calc(100% / var(--columns));
}
</style>
通过将 display
属性从 block
修改为 table
,您应该能够在打印时保持表格的自适应宽度效果。