4

前端一键打印解决方案

 3 years ago
source link: https://zhuanlan.zhihu.com/p/83068956
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

前端一键打印解决方案

北京奇观技术有限责任公司 软件开发工程师


v2-e0c1562fad45942963268af53141d7c5_b.jpg

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

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

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

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

2生成可打印的文档

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

v2-7e4fe81fc2ca1fd3ef8dafd07ee8e67f_720w.jpg

1 页面设置

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

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

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">  兹委托:<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);

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


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK