场景:
最近在公司做开发,有个需求需要页面打印功能,作为前端半桶水都不到,只会改页面的我,一脸懵逼,公司里也没人系统的做过,按照惯例,本着有事找度娘的心态(我一直认为我们现在遇到的70%-80%的问题,肯定前人有遇到过),上百度搜索一圈,发现还是有大量的帖子,但很多都是重复的,且并不十分符合我当前的需求,但通过查阅大佬们的帖子,我对js打印的处理方向有个大致的了解。话不多说,开始进入正题,记录下我本次的 js 打印页面开发。
需求:
1.单个指定订单打印
2.多个订单批量打印
3. 页眉页脚设置(页眉设置完成,页脚半成品)
需求寥寥数语,很简单,没什么可汲取的有效信息,再加一份Word打印的效果模板,开始干活,整个开发期间,我改了好几版,为了节约大家的时间,先前的几个被我推翻的历史版本就不再阐述,本文仅记录我的最终提交的版本。
开发记录:
当前打印版本思路是使用页面放置一个 隐藏的iframe 的方式,实现打印内容动态加载,而不影响我页面的其他功能。
将打印页面单独写好(页面样式和打印样式会有不同),我当前项目前端采用的是 thymeleaf 模板,后端 SpringBoot ,在打印页面中,为保证打开打印时,需要打印的数据能完整展示,不使用js ajax 动态加载,直接使用 thymeleaf 模板语言进行页面加载赋值,后端转发请求页面时,把值处理好,设置在model 中,前端直接取值使用。
自定义页眉页脚:
css样式:
/** 隐藏系统默认的页眉页脚 **/
@page {
size: auto; /* auto is the initial value */
margin: 0mm; /* this affects the margin in the printer settings */
}
/** 设置默认的页眉页脚默认为隐藏 **/
.beforeHeader,
.afterFooter {
display: none;
}
@media print {
/* 打印时显示 */
.beforeHeader,
.afterFooter {
display: block;
}
}
页面:
通过我本人的多次测试,页面距离最外层打印区域差不多 20-25px就可以了。
批量打印只需要传入多个id查询对应的数据,返回的结果为list ,这样在前端页面上就可以采用 thymeleaf 的循环方法进行动态生成打印内容,兼容 单个打印和批量打印。
批量打印是就涉及到分页问题,对于js 调用打印机,只需要在我们的单个打印内容的最外层加上样式:page-break-after:always; 即可,这样打印机就会打印完我们单个打印内容后,不管当前纸张是否已经填满,都会换一张纸重新打印。
讲完了页面构造和赋值,现在讲下js的操作,js 的操作及其简单:
在触发打印事件方法中,加上动态更新我们iframe的src页面路径,从而时当前iframe的页面内容都是最新的。
$("#printIframe").prop("src", u.formatWebUrl("页面路径?ids=" + ids));
printIframe 为先前页面上放置的隐藏iframe的id,单单加上这个还不够,为保证触发浏览器打印时,页面数据都是加载完成的,我们还需要监听 iframe的加载完成事件,等页面数据加载完了以后再触发打印事件。
//监听iframe加载完成后,触发打印事件
var iframe = document.getElementById("printIframe");
if (iframe.attachEvent) {
iframe.attachEvent("onload", function() {
document.getElementById('printIframe').contentWindow.print();
});
} else {
iframe.onload = function() {
document.getElementById('printIframe').contentWindow.print();
};
}
printIframe 为先前页面上放置的隐藏iframe的id。
至此,一个采用 iframe 触发浏览器打印功能开发完成,当前例子,会打开打印的预览页面,和打印机设置页面(如下图),但不会打开我们自己写的页面,连接上打印机,点击页面上的打印按钮就可以实现打印了。
总结:
和往常的开发过程一样,还没做时感觉好难,中间会几经坎坷,但做完后回头看,却感觉并没有什么难点,感觉都很简单。
本次 js 打印页面的开发,没中不足的就是页脚的设置,和开头时说的一样,只成功了一半,可以自定义,但是没办法做成页码,一个页面一张纸的,比如 1,2,3 没问题,可以通过获取当前的循环次数来设置页数,但一个页面多张纸的,比如:1-1,1-2,2-1,2-2,2-3暂时就不知道怎么做了,如果大佬们针对这个有好的解决办法,欢迎留言。
最后,在这里默默的感谢网上各位大佬给的开发思路:
web使用window.print()实现分页批量打印 :https://blog.csdn.net/weixin_41488294/article/details/81705171
设置页面页脚:https://segmentfault.com/q/1010000006138115