首发于前端开发
前端一键打印解决方案

前端一键打印解决方案

首先我来介绍下业务背景:我们在做一款类似于中介工作的软件,为了帮助用户快速办理各种业务,获得各种证件。为了能够最高效的解决用户懒得做的工作。我们业务的核心就是:机器能去做的事情绝不要让人去做。

为此我们做下如下努力:1打通业务流程2puppteer流程化机器人3快速生成材料申报

下面我将介绍前端一键打印解决方案

1首先我们需要收集用户信息(随便什么app、小程序、网站了都可以)

2生成可打印的文档

这里其实很多技术比如PHPExcelJAVA EXCEL等等后端方案把数据通过我们想要的方式生成excel文件,而前端打印其实是通过浏览器打印功能来实现打印效果的做法。比如下面这张委托书。


1 页面设置

@page 规则用于指定打印页面的一些属性,包括纸张尺寸、方向、页边距、分页等特性。·

@page :pseudo-class {
  size: A4 landscape;
  margin:2cm;
}


2 分页

page-break-before用于设置元素前面的分页行为,可取值:

  • auto默认值。如果必要则在元素前插入分页符。
  • always在元素前插入分页符。
  • avoid避免在元素前插入分页符。
  • left在元素之前足够的分页符,一直到一张空白的左页为止。
  • right在元素之前足够的分页符,一直到一张空白的右页为止。
  • inherit规定应该从父元素继承 page-break-before 属性的设置。

page-break-after设置元素后的分页行为。取值与page-break-before一样。

page-break-inside设置元素内部的分页行为。取值如下:

  • auto默认。如果必要则在元素内部插入分页符。
  • avoid避免在元素内部插入分页符。
  • inherit规定应该从父元素继承 page-break-inside 属性的设置。
@media print {
  section {page-break-before: always;}
  h1 {page-break-after: always;}
  p {page-break-inside: avoid;}
}


3分页保留行数

orphans设置当元素内部发生分页时必须在页面底部保留的最少行数。

widows设置当元素内部发生分页时必须在页面顶部保留的最少行数。

@media print {
  p {orphans:3; widows:2;}
}


其他

  1. 对于页面上有显示而不想打印的内容,可以将其display设置为none来避免打印。
  2. 需要打印的内容尽量避免float,有些浏览器不会正确的打印浮动的内容。
  3. 分页打印或换页打印:page- break-beforepage-break-after CSS属性并不会修改网页在屏幕上的显示,这两个属性是用来控制文件的打印方式。
  4. 网页整体布局直接根据打印内容调整。用打印的方式预览


3 批量打印解决方案

1 Ant Design 数据表格



批量勾选需要打印材料的店铺

然后处理用户数据

liveProveHandleOk =() =>{
        let data = this.state.selectedRows;
        let length = data.length;
        if(length == '0'){
            message.error('未选择任何店铺');
            return 0;
        }

        let list = [];
        for(let i=0;i<length;i++){
            let item = {};
            item.bussiness_name = data[i].bussiness_name;
            item.user_name = data[i].user_name;
            item.user_phone = data[i].user_phone;
            item.id_card_number = data[i].id_card_number;
            item.gongwei = data[i].gongwei;
            list.push(item);
        }
        list = JSON.stringify(list);
        window.open(host + 'table2.html?list='+list);
        this.setState({
            liveProveVisible:false
        })
    }

拿到列表每一条勾选上的用户数据,然后重新拼接去掉不用的数据。

因为我们通过window.open的方式打印材料页面,数据通过url传递,而url不易过长


2 材料页面处理数据

这里我们通过handlebars模板引擎处理数据 生成多份打印材料 从而实现批量打印材料的效果

<script src='https://cdnjs.cloudflare.com/ajax/libs/handlebars.js/4.1.2/handlebars.js'></script>
<script id="list" type="text/x-handlebars-template">
	{{#each data}}
	 <div class="container">
	    <div class="content" style="margin-top: 100px;">
	        <div class="hei" style="text-align: center; font-size: 30px;margin-bottom: 30px;"><span style="text-decoration: none;">办理税务事项委托书</span></div>
			<p class="text1">国家税务总局景宁畲族自治县税务局:</p>
			<p class="text1">&emsp;&emsp;兹委托:<span id="name">{{this.name}}</span> (身份证:<span id="id">{{this.id_card_number}}</span>)办理 <span id="bussiness_name">{{this.bussiness_name}}</span> 税种核定、税盘发行及发票领取等相关事宜。</p>
			<div class="right hei" style="margin-top: 200px;"><span id="bussiness_name2" style="text-decoration: none;"></span></div>
			<div class="right hei" style="margin-bottom: 170px; padding-right: 150px;"><span style="text-decoration: none;">委托人(盖章)</span></div>
			<div class="right hei"><span style="text-decoration: none;">日期: <span id="year">{{this.year}}</span>年<span id="month">{{this.month}}</span>月<span id="today">{{this.today}}</span>日</span></div>
		</div>
	</div>
	{{/each}}
</script>


3 打印 关闭

//信息全部展示完成后打印页面
window.print();   
//打印完成或是取消后页面关闭
setTimeout("window.close();", 0);

实现效果:管理员勾选需要打印材料的用户-》点击打印材料 -》弹出窗口提示打印-》 管理预览打印文件点击确定-》 打印成功 -》 页面自动关闭

编辑于 2019-09-18 21:59