CSS 分页媒体
Chromium 对 CSS Paged Media 的支持有限,仅部分实现(如 page-break
),而
position: running
和 content: element
等高级功能不支持。这使得页眉/页脚设置较为复杂。
Paged.js
为弥补 Chromium 短板,可引入 Paged.js 库。它能解析网页并自动处理分页、页眉/页脚和页码。目前,该库维护活跃度较低,但适用于大多数场景。
例子
以下示例使用 Paged.js 实现动态页眉/页脚。注意:header
和 footer
必须置于 main
之前,否则 footer
无效。
<!doctype html>
<html lang="en">
<head>
<meta charset="UTF-8">
<title>Hi, bkhtmltopdf!</title>
<style>
* {
margin: 0;
padding: 0;
box-sizing: border-box;
}
@page {
margin: 1em;
background: darkgreen;
}
.page-break-after {
page-break-after: always;
text-align: center;
color: white;
}
@media print {
@page {
margin: 3rem 0;
@top-center {
content: element(header);
}
@bottom-center {
content: element(footer);
}
}
header {
height: 3rem;
position: running(header);
background: darkblue;
color: gray;
}
footer {
height: 3rem;
position: running(footer);
background: darkcyan;
color: darkgray;
}
.page-number::after {
content: counter(page) ' of ' counter(pages);
}
}
</style>
</head>
<body>
<header>
<h1>
Header, <span class="page-number"></span>
</h1>
</header>
<footer>
<h1>
Footer, <span class="page-number"></span>
</h1>
</footer>
<main>
<div class="page-break-after">
<h1>Page 1</h1>
</div>
<div class="page-break-after">
<h1>Page 2</h1>
</div>
<div class="page-break-after">
<h1>Page 3</h1>
</div>
</main>
<script>
window.PagedConfig = {auto: false};
</script>
<script src="https://unpkg.com/pagedjs/dist/paged.polyfill.js"></script>
<script>
class MyHandler extends Paged.Handler {
constructor(chunker, polisher, caller) {
super(chunker, polisher, caller);
}
afterPreview(pages) {
console.debug('print')
}
}
Paged.registerHandlers(MyHandler);
window.addEventListener('DOMContentLoaded', () => {
window.PagedPolyfill.preview();
})
</script>
</body>
</html>
代码示例中的 console.debug('print')
是必须的,且 HTML to PDF 的 waitUntil
必须是 manual,否则 bkhtmltopdf 将会持续等待打印操作。
渲染时机说明
在 HTML to PDF 中,必须设置 waitUntil: "manual"
,否则 Paged.js 处理未完成即开始打印。
由于 waitUntil
的可能值为 load
、domcontentloaded
和 manual
,如果不使用 manual
模式,页面加载完成后会立即执行打印操作,而此时 Paged.js 可能尚未执行完毕。
注意
示例中的 console.debug('print') 是必需的,用于信号 Paged.js 预览完成。