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

模糊逻辑
• 阅读 6215

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

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

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

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

总的说来,实现打印的方式也无非就是这两种方法,当然这也不排除使用插件,我看了下回答,有一个利用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('<html><head><title>' + document.title  + '</title>');
    mywindow.document.write('</head><body >');
    mywindow.document.write('<h1>' + document.title  + '</h1>');
    //代码的着重点就在此处
    mywindow.document.write(document.getElementById(el).innerHTML);
    mywindow.document.write('</body></html>');

    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。像如下这样:

<div class="noprint">//这里是不打印的区域</div>
<div class="print">//这里是打印的区域</div>

然后css就这样写:

@media print{
   .noprint{
       display:none;
   }
   .print{
       display:block;
   }
}

值得注意的就是如果页面中有元素没有设置display:none,而且它又在页面中没有视觉显示,但是却有定位属性,就需要将它的定位属性给去掉,如下图所示:

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

我的按钮代码大致是这样的:

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

我利用iview的table组件来作为打印的元素,如下图所示:

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

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的样式布局造成的,iview的底层用了两个table元素来封装这个表格组件,我没办法,只好选择不用iview的table组件,自己手写table元素以及样式(如果有更好的方法希望有大佬指点迷津)。为此我还特意写了一个demo来测试,测试代码如下:

页面需要引入:

<link rel="stylesheet" type="text/css" href="http://unpkg.com/iview/dist/styles/iview.css">

<script type="text/javascript" src="http://vuejs.org/js/vue.min.js"></script>

<script type="text/javascript" src="http://unpkg.com/iview/dist/iview.min.js"></script>


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:

<div id="app">
   <div class="table">
    <i-Table :columns="columns1" :data="data1" id="print"></i-Table>
   </div>
   <i-button type="primary" @click="window.print()" class="noprint">打印</i-button>
</div>

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'
            }

          ]
        }
    }
})


运行效果如下图所示:

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

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

点赞
收藏
评论区
推荐文章
Wesley13 Wesley13
4年前
java 根据图片文字动态生成图片
今天在做热敏打印机打印二维码,并有文字描述,想到的简单的方法就是根据热敏打印机的纸张宽度和高度,生成对应的图片,如下:packagecom.orisdom.utils;importlombok.extern.slf4j.Slf4j;importjavax.imageio.ImageIO;importjava.awt.;importja
不才 不才
3年前
前端实现在浏览器中打印网页
前端数据报表打印方案背景项目:vueelementui需求:web端连接打印机打印报表功能关键词:浏览器端连接打印机打印报表调研首先,前端调用打印只有两种方式,使用window.print()和调用网络打印机。window.print这个是浏览器开放的api一般快捷键ctrlp或右键都也能调用。可以通过媒体查询的方案进行局部打印,也就是隐
Jacquelyn38 Jacquelyn38
4年前
手把手教你实现一个Vue无限级联树形表格(增删改)
前言平时我们可能在做项目时,会遇到一个业务逻辑。实现一个无限级联树形表格,什么叫做无限级联树形表格呢?就是下图所展示的内容,有一个祖元素,然后下面可能有很多子孙元素,你可以实现添加、编辑、删除这样几个功能。资源JavaScript框架:vue.jsUI框架:ElementUI源码这里需要重点说明的是,主要使用了递归的算法以及给数
Wesley13 Wesley13
4年前
CAD打印文字不显示怎么办
当我们给CAD文件打印的时候,会遇到很多问题,从而无法得到理想的打印效果。例如打印CAD图纸发现其中的文字不显示,对此,我们只要进行相应的CAD打印设置就可以解决这个问题  1.用迅捷CAD编辑器打开想要打印的CAD文件。运行迅捷CAD编辑器,在左侧上角点击“文件”“打开”,在打开窗口找到并选择相应CAD文件,然后在窗口右下角点击“打开”即可在迅捷CA
Stella981 Stella981
4年前
JavaScript队列
队列队列是遵循FIFO(FirstInFirstOut,先进先出)的一组有序的项。在计算机科学中,最常见的是打印队列,比如我需要打印五份文档,就先打开每个文档,再点击打印按钮,则每一个文档都会被发送到打印队列。第一个发送到打印队列的文档会首先打印,依次类推,直到打印完所有五篇文档。此外,需要说明一下的是,在linux中,FIFO是一种特殊的文
Wesley13 Wesley13
4年前
Spread for Windows Forms高级主题(7)
表单打印的多个部分都可以进行自定义,大多数的自定义选项存在于PrintInfo对象中。大多数打印选项是在PrintInfo对象上进行设置,并在表单级别上应用。当你执行打印操作时,你将一个特定的表单发送给使用这些设置的打印机。如果你想为不同的表单使用不同的打印设置,那么你可能需要重置PrintInfo对象,然后在表单打印的间隔内做必要的修改。深入理解打
Stella981 Stella981
4年前
FastReport 打印模版页(TFrxReportpage)复制
遇到一个奇葩的需求。一般情况下我们打印单据,用FastReport设置打印格式,也就是就设一个模版页而己,就是一种单据格式。如果打印的单据数据多了就自动打印多页了,他们的格式是一样的。也就是读同一个模版页。现的需求是,如果打印N页内容。每一页的格式除了表体外是一样的(也可能部份不同)。而表体取自不同的数据集(也就是读取不同的FDQuery),需要设置不同
Wesley13 Wesley13
4年前
asp.net调用Lodop实现页面打印或局部打印,可进行打印设置或预览
<%@PageLanguage"C"AutoEventWireup"true"CodeFile"WebPrint.aspx.cs"Inherits"WebPrint"%<!DOCTYPEhtmlPUBLIC"//W3C//DTDXHTML1.0Transitional//EN""http:/
Stella981 Stella981
4年前
ReactNative state更新,视图不更新的问题
开发中遇到这样的问题,我更新了state一个数组的某个元素的选中状态,打印出的数据也显示修改正确了,但是界面却没更新。例如下图点击某项修改选中状态。!(https://oscimg.oschina.net/oscnet/c3291a62b5f638d1e35dd7a719ade39f226.png)代码中之前是这样写的,结果界面没有更新。
Python进阶者 Python进阶者
2年前
盘点一个Python自动化办公需求,实现数据自动填充
大家好,我是皮皮。一、前言前几天遇到了一个小需求,粉丝自己在实际工作中的需求,需要把下图的表格内容,自动填充到目标表格中去,省得挨个去复制粘贴了,而且还十分容易出错。原始表格如下图所示:目标表格如下图所示:二、实现过程这里【枫涧澈浪】大佬给了一个代码,如下
桌面运维工具之打印机驱动安装
1.前言桌面运维同学经常会处理打印机驱动安装这类工单,手动安装打印机驱动通常包含以下步骤:1.根据打印机型号网上查找对应打印机驱动2.使用cmd命令进入管理员界面3.将打印机驱动添加到window系统中人工安装需要经过三个步骤,操作繁琐,效率较低。基于此,