今天遇到一个需求,看起来也比较简单,就是实现一个打印功能。页面中有一个表单,将表单里的数据对应添加到表格中,然后点击打印按钮,实现预览打印,这里我用的是iview框架,如下图所示:
实现打印的功能,很明显就要用到window.print()方法,但是如果不做限制,那么这个方法就会将页面内的所有内容给打印出来,这肯定是不满足需求的。有两种方法来实现,一种是利用CSS的媒体查询,另一种则是使用js。
我这里采用的是第一种办法,我在stackoverflow上大致搜了一下,曾经有人问过打印的问题。如下图所示:
总的说来,实现打印的方式也无非就是这两种方法,当然这也不排除使用插件,我看了下回答,有一个利用jquery封装的插件,大致去看了下这个插件,也并没有达到我的要求,而且代码调用传的参数也有些多,索性我就放弃了。想要了解这个插件的可以前往这个网址:[]
首先说下为什么用js方式实现打印不行,因为在这个系统当中,我写了好几个样式文件,如果使用js方式来实现打印,那么就势必要引入多个css,而且css文件还不好引入,这是其一,其二就是还要操作DOM取得要打印的内容。以下是js实现打印的具体代码:
function Print(el){ var mywindow = window.open('', '', 'height=800,width=1000'); mywindow.document.write('' + document.title + ' '); mywindow.document.write(''); mywindow.document.write('' + document.title + '
'); //代码的着重点就在此处 mywindow.document.write(document.getElementById(el).innerHTML); mywindow.document.write(''); mywindow.document.close(); // necessary for IE >= 10 mywindow.focus(); // necessary for IE >= 10*/ mywindow.print(); mywindow.close(); return true;}
所以我索性采用了第二种方法,就是利用css媒体查询,css专门有个与打印有关的媒体查询,代码结构如下:
@media print{ //具体代码}
我们只需要将不打印的元素的display属性设置为none,打印的元素的display属性设置为block即可。这个代码里还涉及到设置元素宽度的单位,目前我只知道有cm和mm。另外还有一个@page属性设置,想了解该属性可自行百度。有人曾说有一个最简便的办法就是在媒体查询里面这样写:
@media print{ *{ display:none; } #myPrint{ display:block; }}
我不知道他是怎么运行出效果的,但至少我是没有成功,我只能通过给不需要打印的元素添加样式类noprint,给需要打印的元素加样式类print。像如下这样:
//这里是打印的区域
然后css就这样写:
@media print{ .noprint{ display:none; } .print{ display:block; }}
值得注意的就是如果页面中有元素没有设置display:none,而且它又在页面中没有视觉显示,但是却有定位属性,就需要将它的定位属性给去掉,如下图所示:
我的按钮代码大致是这样的:
我利用iview的table组件来作为打印的元素,如下图所示:
printHead和printData就是要打印的数据,print方法里面我是如此写的:
print() { this.printHead = [ { title: "企业/团队名称", key: 'client_name' }, { title: "法人/负责人", key: 'lp_name' }, { title: "团队人数", key: 'number_of_employees' }, { title: "联系电话", key: 'contact_information' }, { title: "QQ/微信", key: 'qq_we_chat' }, { title: "注册地址", key: 'registered_address' }, { title: "成立时间", key: 'time_of_establishment' }, { title: "审核状态", key: 'status' }, { title: "申请时间", key: 'created_time' }, { title: "经营简介", key: 'enterprise_introduction' }, { title: "审核意见", key: 'reason' } ]; this.printData = []; this.printData.push(this.curAudit); this.printing = true; setTimeout(function(){ window.print(); },1000)},
这里我想大概是因为页面在渲染iview组件的原因,所以必须要延迟运行打印方法window.print()才会真正执行到打印功能。但是我却碰到一个很奇怪的问题,如下图所示:
这个问题足足困扰了我一下午,我一下午都在想为什么会出现这样的结果,后来我终于明白了,是iview的样式布局造成的,iview的底层用了两个table元素来封装这个表格组件,我没办法,只好选择不用iview的table组件,自己手写table元素以及样式(如果有更好的方法希望有大佬指点迷津)。为此我还特意写了一个demo来测试,测试代码如下:
页面需要引入:
css:
.noprint{ display: block; margin:20px auto;}.table{ width: 100%;}.table th,.table td{ text-align: center;}@media print{ .noprint{ display: none; } .print{ display: block; }}
html:
js:
new Vue({ el: '#app', data(){ return { columns1: [ { title: 'Name', key: 'name' }, { title: 'Age', key: 'age' }, { title: 'Address', key: 'address' }, { title: 'date', key: 'date' } ], data1: [ { name: 'John Brown', age: 18, address: 'New York No. 1 Lake Park', date: '2016-10-03' }, { name: 'Jim Green', age: 24, address: 'London No. 1 Lake Park', date: '2016-10-01' }, { name: 'Joe Black', age: 30, address: 'Sydney No. 1 Lake Park', date: '2016-10-02' }, { name: 'Jon Snow', age: 26, address: 'Ottawa No. 2 Lake Park', date: '2016-10-04' } ] } }})
运行效果如下图所示:
当然如果有大佬知道还有更好的办法,希望指点一下,也希望此文能帮助遇到此坑的人。另外第一次写文章,如有排版等不好,敬请谅解。