资讯专栏INFORMATION COLUMN

关于iview框架实现打印指定区域所碰到的坑

quietin / 3154人阅读

摘要:今天遇到一个需求,看起来也比较简单,就是实现一个打印功能。有两种方法来实现,一种是利用的媒体查询,另一种则是使用。

今天遇到一个需求,看起来也比较简单,就是实现一个打印功能。页面中有一个表单,将表单里的数据对应添加到表格中,然后点击打印按钮,实现预览打印,这里我用的是iview框架,如下图所示:

实现打印的功能,很明显就要用到window.print()方法,但是如果不做限制,那么这个方法就会将页面内的所有内容给打印出来,这肯定是不满足需求的。有两种方法来实现,一种是利用CSS的媒体查询,另一种则是使用js。

我这里采用的是第一种办法,我在stackoverflow上大致搜了一下,曾经有人问过打印的问题。如下图所示:

总的说来,实现打印的方式也无非就是这两种方法,当然这也不排除使用插件,我看了下回答,有一个利用jquery封装的插件,大致去看了下这个插件,也并没有达到我的要求,而且代码调用传的参数也有些多,索性我就放弃了。想要了解这个插件的可以前往这个网址:[https://github.com/jasonday/p...]

首先说下为什么用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"
            }

          ]
        }
    }
})


运行效果如下图所示:


当然如果有大佬知道还有更好的办法,希望指点一下,也希望此文能帮助遇到此坑的人。另外第一次写文章,如有排版等不好,敬请谅解。

鄙人创建了一个QQ群,供大家学习交流,希望和大家合作愉快,互相帮助,交流学习,以下为群二维码:

文章版权归作者所有,未经允许请勿转载,若此文章存在违规行为,您可以联系管理员删除。

转载请注明本文地址:https://www.ucloud.cn/yun/98385.html

相关文章

  • vue配合iview/element等ui实现界面效果起步

    摘要:与都是与配合使用的框架,用法与配置基本一致,在此,我以为例,教你如何起步。如果我的文字对你有用,记得点心关注我,给一点点动力支撑。 iview与element都是与vue配合使用的ui框架,用法与配置基本一致,在此,我以iview为例,教你如何起步。*首先,你需要有一定的vue基础,如果你还是个小白,可以去我之前介绍如何搭建一个vue项目先看看,点击下面的链接就OK了http://ww...

    Object 评论0 收藏0
  • vue配合iview/element等ui实现界面效果起步

    摘要:与都是与配合使用的框架,用法与配置基本一致,在此,我以为例,教你如何起步。如果我的文字对你有用,记得点心关注我,给一点点动力支撑。 iview与element都是与vue配合使用的ui框架,用法与配置基本一致,在此,我以iview为例,教你如何起步。*首先,你需要有一定的vue基础,如果你还是个小白,可以去我之前介绍如何搭建一个vue项目先看看,点击下面的链接就OK了http://ww...

    tommego 评论0 收藏0
  • iView 发布 3.0 版本,以及开发者社区等 5 款新产品

    摘要:相对时间组件锚点组件面板分割组件分割线组件单元格组件相对时间组件用于表示几分钟前几小时前等相对于此时此刻的时间描述。单元格组件在手机上比较常见,在上则常用于固定的侧边菜单项。开发者社区这是发布会最劲爆的一款产品了。 showImg(https://segmentfault.com/img/bVbeuj6?w=2864&h=1458); 7 月 28 日,我们成功地召开了 iView 3...

    FreeZinG 评论0 收藏0
  • Laravel-Vue-SSR-SPA 服务端渲染/单页面渲染实现骨架

    摘要:提供服务端渲染单页面渲染实现骨架同时集成打包构建文件名实现内置等套件提供端渲染方案前后端分离单页面方案前后端分离单页面方案等三种常见方案项目地址欢迎项目需求基于和提供的强大的功能组合并根据已有项目实践经验提供完整的集成方案帮助快速 Laravel-Vue-SSR-SPA 提供服务端渲染/单页面渲染实现骨架, 同时集成webpack打包构建 MD5文件名/gzip 实现, 内置 vue-...

    zr_hebo 评论0 收藏0

发表评论

0条评论

quietin

|高级讲师

TA的文章

阅读更多
最新活动
阅读需要支付1元查看
<