分享几个前端调整打印文档的常见问题,以及可以如何解决这些问题。
1.如何控制分页?
第一个场景,页面存在两个div,按下ctrl+p打印页面,可以看到两个div紧贴在同一页里,如果需要这两个div打印在不同页,该如何处理。
解决这个问题的关键,是我们该如何告诉页面需要分页。这就引出了第一个css属性 page-break-after,以及其扩展版本 break-after。以 page-break-after 为例,page-break-after: always; 可以强制在元素之后添加分页符。
div {
page-break-after: always;
}
添加之后的效果如下:
打印时最后多出一页空白页?
div:last-child{
page-break-after: auto;
}
2.如何控制不分页?
第二个场景,当打印文档的数据内容非常多,超出了一页,会自动分页。假设这是一个表格,表格中有文字,用户肯定不希望内容被分页,此时该如何处理。
既然CSS能控制如何分页,那么能不能控制如何不分页呢?当然是可以的,page-break-inside 和其扩展版本 break-inside 属性,使用 break-inside: avoid; 可以避免在元素内部插入分页符。
div {
break-inside: avoid;
}
添加之后,div二整块挪到了第二页,没有被分页符分隔。
这里可以再举例一个实际的应用,给table中的tr添加不分页之后,就实现了如下单元格自动分页且不被分隔的效果。
前面说了break-after 和 break-inside 属性,其实还有一个 break-before ,根据实际情况使用即可,三者的关系如下:
break-after 定义元素之后如何处理中断,break-before 定义元素之前应如何处理中断, break-inside 定义了当前元素如何处理中断。
3.如何在页脚增加页码?
第三个场景,产品希望在页脚添加页码,便于多页打印时统计更方便,效果如下:
这个问题其实应该分为两个部分来看,第一部分,如何定位页脚,第二部分,如何统计页码。
先看第一个问题,如何定位页脚。我们是使用前端提供打印模版,后端渲染模版的方式来实现打印的,打印模版其实就是一个HTML文件,那么在HTML中 position: fixed;bottom: 0; 的位置是不是就算最底部的页脚了?可以看下图,图中包含“打印人,打印时间”的div元素就是使用 position: fixed;bottom: 0;right:0 定位的,可以看到相较于页脚位置显示1/1的页码还是有一段距离的。似乎打印时,在HTML模版四周会添加额外的页眉页脚和左右边距。
那么前端是否可以判断当前正在打印,并做额外操作?我们知道 @media 规则和 @page 规则,都可以在打印文档时修改某些CSS属性。我们需要的页脚可以在@page规则中找到答案(修改四周区域的大小也是可以的),语法如下:
@page <page-selector-list> {
<page-body>
}
重点关注page-body,下图中间大面积空白位置是我们的HTML文档,而四周各个红框标注的位置就是page-body的值,使用bottom-center就可以设置我们的页脚区域。
接下来就可以解决页码的统计了,不卖关子了,这里我使用的是CSS函数 counter() ,初始化page计数器为1,每一页加1,pages为总页数。最终实现为:
@page {
counter-increment: page;
counter-reset: page 1;
@bottom-center {
content: counter(page) " / " counter(pages);
}
}
最后还有一个优化,如果想把上面“打印人,打印时间”这一行,显示在页脚区域 bottom-right-corner 的位置,有哪些解决方案?实现的关键是如何取到打印人和打印时间的数据,对于这一问题,CSS表达式 attr() 或许可以起到帮助。
以上就是本次分享的全部内容~