为window.print()添加分页页码:多页div仅首页显示页眉问题
解决打印时跨页div每页显示独立页眉及页码的问题
问题核心
你当前的代码仅在每个page-break div开头插入一个静态页眉元素,浏览器自动分页后,后续页面不会复制该元素,导致只有第一页显示页眉。要实现每页重复显示页眉且每个div页码独立计数,需要结合CSS打印布局特性与JS逻辑来完成。
具体实现
1. 添加打印专用CSS样式
在页面中插入以下CSS,专门控制打印时的页眉展示与页码计数:
@media print { /* 全局重置计数器,每个page-break div单独重置自身页码 */ body { counter-reset: page-num; } .page-break { counter-reset: page-num; page-break-after: always; /* 每个div打印完成后强制分页,确保下一个div页码从头开始 */ } /* 定义页眉样式,标记为可在每页重复的running元素 */ .print-header { position: running(print-header); display: flex; justify-content: space-between; padding: 0 10px; align-items: center; font-weight: bold; font-size: 15px; } /* 配置每页顶部区域显示页眉 */ @page { size: letter; margin-top: 35px; /* 预留页眉展示空间 */ @top-left { content: element(print-header); } } /* 每发生一次分页,页码计数器自增1 */ .page-break > * { counter-increment: page-num; } /* 屏幕视图下隐藏打印页眉 */ .print-header-div { display: none; } } @media screen { .print-header { display: none; } }
2. 修改JS逻辑代码
调整JS逻辑,为每个div生成包含身份信息与总页数的页眉,并动态配置页码显示:
const testx = () => { const docs = document.querySelectorAll('.page-break'); // 创建页眉元素的工具函数 const createHeader = (identity, totalPages) => { const header = document.createElement('div'); header.className = 'print-header'; // 左侧身份信息 const leftEl = document.createElement('div'); leftEl.textContent = identity; // 右侧总页数,配合CSS计数器显示完整分页信息 const rightEl = document.createElement('div'); rightEl.textContent = totalPages; header.appendChild(leftEl); header.appendChild(rightEl); return header; }; docs.forEach((div, idx) => { // 提取身份信息,缺失时使用默认值 const reqCode = div.querySelector('#RequestCode')?.value || 'Unknown Request Code'; const lastName = div.querySelector('.print-last-name')?.innerHTML || 'Unknown Last Name'; const firstName = div.querySelector('.print-first-name')?.innerHTML || 'Unknown First Name'; const dob = div.querySelector('.print-dob')?.innerHTML || 'Unknown DOB'; const identity = `${reqCode} ${lastName} ${firstName} ${dob}`; // 计算当前div的总页数 const totalPages = calculatePageCount(div); // 将页眉插入到div开头 const header = createHeader(identity, totalPages); div.insertBefore(header, div.firstChild); // 动态添加CSS,配置当前div每页的完整分页信息 const style = document.createElement('style'); style.dataset.printStyle = ''; style.textContent = ` @page :nth(${idx + 1}) { @top-right { content: "Page " counter(page-num) " of ${totalPages}"; } } `; document.head.appendChild(style); }); // 触发打印对话框 window.print(); // 打印完成后清理临时添加的元素与样式 setTimeout(() => { document.querySelectorAll('.print-header').forEach(el => el.remove()); document.querySelectorAll('[data-print-style]').forEach(el => el.remove()); }, 1000); }; // 修复原函数的冗余问题,添加临时元素清理逻辑 function calculatePageCount(content, pageHeight = 1056, pageWidth = 216) { let contentEl; if (typeof content === 'string') { contentEl = document.createElement('div'); contentEl.innerHTML = content; } else if (content instanceof HTMLElement) { contentEl = content.cloneNode(true); } else { throw new Error('Invalid content: must be HTML string or DOM element'); } contentEl.style.cssText = ` visibility: hidden; position: absolute; width: ${pageWidth}mm; top: -9999px; `; document.body.appendChild(contentEl); const totalPages = Math.ceil(contentEl.scrollHeight / pageHeight); document.body.removeChild(contentEl); // 清理临时DOM元素 return totalPages; }
3. 关键逻辑说明
- CSS Paged Media:通过
position: running标记页眉为可重复元素,浏览器打印时会自动将其渲染到每页顶部。 - 独立页码计数:每个
page-breakdiv单独重置页码计数器,确保不同div的页码从1开始独立计数。 - 动态总页数:JS计算每个div的总页数后,动态生成CSS规则,与当前页码计数器组合成完整的分页信息。
注意事项
- 主流浏览器(Chrome、Firefox)对CSS Paged Media支持良好,建议优先在这些浏览器测试。
- 打印前需检查页面边距设置,避免页眉内容被截断。
- 打印后的清理步骤可选,但建议保留,避免页面残留多余元素影响正常展示。
内容的提问来源于stack exchange,提问作者wenreloz
相关产品推荐
相关产品推荐

