如何虚拟设置800px宽时,获取适配@page样式的页面高度?
解决单页连续PDF打印的问题
核心方案
不用实际修改原页面宽度,而是通过克隆页面DOM并在隐藏容器中模拟800px宽度的打印样式环境,计算出真实高度后再应用到@page规则。
具体实现步骤
- 克隆整个页面的DOM结构,完整复制内联、外部样式及元素
- 创建一个绝对定位的隐藏div容器,固定宽度为800px,放置在视口外
- 对克隆的DOM应用打印专属样式:移除导航、页脚,显示/隐藏指定元素,模拟打印时的样式变化
- 等待克隆DOM渲染完成后,获取容器的
scrollHeight,这就是800px宽度下的真实页面高度 - 动态生成
@page样式规则,将尺寸设为800px [计算出的高度]px - 触发
window.print(),打印完成后移除临时创建的隐藏容器和样式
代码示例
$(document).ready(function() { $('#print-trigger').click(function() { // 克隆原页面DOM const pageClone = $('body').clone(); // 创建隐藏模拟容器 const mockContainer = $('<div>').css({ position: 'absolute', top: '-9999px', left: '-9999px', width: '800px', visibility: 'hidden' }); // 给克隆DOM应用打印样式 pageClone.find('.navbar, .page-footer').remove(); pageClone.find('.print-show').show(); pageClone.find('.print-hide').hide(); // 将克隆DOM放入容器并添加到页面 mockContainer.append(pageClone); $('body').append(mockContainer); // 等待渲染完成后计算高度 setTimeout(function() { const realHeight = mockContainer[0].scrollHeight; // 动态设置@page规则 const printStyle = document.createElement('style'); printStyle.innerHTML = ` @page { size: 800px ${realHeight}px; margin: 0; } /* 同步打印时的样式 */ .navbar, .page-footer { display: none !important; } .print-show { display: block !important; } .print-hide { display: none !important; } `; document.head.appendChild(printStyle); // 执行打印 window.print(); // 清理临时元素 setTimeout(function() { mockContainer.remove(); document.head.removeChild(printStyle); }, 100); }, 200); }); });
关键注意事项
- 必须等待克隆DOM完全渲染再计算高度,否则会得到不准确的数值
- 克隆DOM时要确保所有样式(包括媒体查询中的打印样式)都被正确继承
- 打印完成后及时清理临时元素,避免干扰原页面的正常运行
内容的提问来源于stack exchange,提问作者Astw41
相关产品推荐
相关产品推荐

