前端杂谈 · Web

JS实现网页区域打印

小编 · 2月9日 · 2021年 ·

实现效果

JS实现网页区域打印-字节智造

准备被打印的区域

首先准备要打印的内容,也可以打印时再填充,通过id="print1" id="print2" 定义需要打印的区域,id值自定义,html中定义如下:

 <el-dialog title="结算订单" :visible.sync="dialogTableVisible" center>
   <div class="createJSD" id="print1">
    //打印区域1
     <div>
       <div>店铺名称:<span></span></div>
       <div>收款单位名称/姓名:<span></span></div>
       <div>开户行:<span></span></div>
       <div>收款账号:<span></span></div>
       <div>收款联系人:<span></span></div>
       <div>店铺联系方式:<span></span></div>
       <div>
         开票备注:
         <template>
           <el-radio label="1">是</el-radio>
           <el-radio label="2">否</el-radio>
         </template>
       </div>
     </div>
     <div>
       <div>结算类型:<span></span></div>
       <div>订单数量:<span></span></div>
       <div>结算总金额:<span></span></div>
       <div>业务负责人:<span></span></div>
     </div>
   </div>

   //打印区域2
   <el-table
     :data="gridData"
     show-summary
     :summary-method="getSummaries"
     id="print2"
   >
     <el-table-column
       align="center"
       type="index"
       label="序号"
     ></el-table-column>
     <el-table-column
       align="center"
       property="date"
       label="订单编号"
     ></el-table-column>
     <el-table-column
       align="center"
       property="name"
       label="商品名称"
     ></el-table-column>
     <el-table-column
       align="center"
       property="address"
       label="销售数量"
     ></el-table-column>
     <el-table-column
       align="center"
       property="address"
       label="销售价"
     ></el-table-column>
     <el-table-column
       align="center"
       property="address"
       label="付款时间 "
     ></el-table-column>
     <el-table-column
       align="center"
       property="address"
       label="实际结算价"
     ></el-table-column>
     <el-table-column
       align="center"
       property="address"
       label="信息服务费"
     ></el-table-column>
   </el-table>

   <span slot="footer" class="dialog-footer">
     <el-button type="primary" @click="getPrint1">打印结算单</el-button>
     <el-button type="primary" @click="getPrint2">打印订单明细</el-button>
     <el-button type="primary">已打款</el-button>
     <el-button type="primary">已开票</el-button>
     <el-button @click="dialogTableVisible = false">取消</el-button>
   </span>
 </el-dialog>

触发JS函数:

// 打印结算单
getPrint1() {
  var iframe;
  var el = document.getElementById("print1");
  iframe = document.createElement("IFRAME");
  var doc = null;
  iframe.setAttribute("id", "print-iframe");
  iframe.setAttribute(
    "style",
    "position:absolute;width:0px;height:0px;left:-500px;top:-500px;"
     //此样式作用,不在页面可视区展示 iframe 
  );
  document.body.appendChild(iframe);
  doc = iframe.contentWindow.document;
  //这里可以自定义打印页面样式
  doc.write(`
  <style>
    body > div {
        background: #dcdfe6;
        border-radius: 10px;
        display: flex;
        justify-content: space-around;
        margin-bottom: 10px;
    }
    body > div > div > div{
        padding: 20px;    
    }
  </style>
  `);
  doc.write("<div>" + el.innerHTML + "</div>");
  doc.close();
  // parent.document.title= `结算订单 + ${}`   可以自定义title
  iframe.contentWindow.focus();
    iframe.contentWindow.print();
  if (navigator.userAgent.indexOf("MSIE") > 0) {
    document.body.removeChild(iframe);
  }
},
// 打印订单明细
getPrint2() {
  var iframe;
  var el = document.getElementById("print2");
  iframe = document.createElement("IFRAME");
  var doc = null;
  iframe.setAttribute("id", "print-iframe");
  iframe.setAttribute(
    "style",
    "position:absolute;width:0px;height:0px;left:-500px;top:-500px;"
    //此样式作用,不在页面可视区展示 iframe 
  );
  document.body.appendChild(iframe);
  doc = iframe.contentWindow.document;
  //这里可以自定义打印页面样式
  doc.write(`
  <style>
    table{
        text-align: center;
    }
  </style>`);
  doc.write("<div>" + el.innerHTML + "</div>");
  doc.close();
  iframe.contentWindow.focus();
  iframe.contentWindow.print();
  if (navigator.userAgent.indexOf("MSIE") > 0) {
    document.body.removeChild(iframe);
  }
},

需要注意的是:通过动态创建iframe来打印的区域,是不带触发页面样式的!,需要通过doc.write(`<style> </style>` ) 写行内样式,也可以引入样式文件:doc.write(“<LINK rel=”stylesheet” type=”text/css” href=”css/print.css”>”);

其他网页区域打印方法

首先准备要打印的内容,也可以打印时再填充,html中定义如下:

<!--startprint-->
<div id="printcontent" style="display:none">
${printContentBody}
</div>
<!--endprint-->

方法一

通过开始、结束标记(startprint、endprint)来打印

function doPrint() { 
    bdhtml=window.document.body.innerHTML; 
    sprnstr="<!--startprint-->"; //开始打印标识字符串有17个字符
    eprnstr="<!--endprint-->"; //结束打印标识字符串
    prnhtml=bdhtml.substr(bdhtml.indexOf(sprnstr)+17); //从开始打印标识之后的内容
    prnhtml=prnhtml.substring(0,prnhtml.indexOf(eprnstr)); //截取开始标识和结束标识之间的内容
    window.document.body.innerHTML=prnhtml; //把需要打印的指定内容赋给body.innerHTML
    window.print(); //调用浏览器的打印功能打印指定区域
    window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
    return false;
}

方法二

通过id选择器来替换内容打印,方法类似第一种

function doPrint2(){
    if(getExplorer() == "IE"){
        pagesetup_null();
    }
    //根据div标签ID拿到div中的局部内容
    bdhtml=window.document.body.innerHTML; 
    var jubuData = document.getElementById("printcontent").innerHTML;
    //把获取的 局部div内容赋给body标签, 相当于重置了 body里的内容
    window.document.body.innerHTML= jubuData; 
    //调用打印功能
    window.print();
    window.document.body.innerHTML=bdhtml;//重新给页面内容赋值;
    return false;
}

function pagesetup_null(){                
    var hkey_root,hkey_path,hkey_key;
    hkey_root="HKEY_CURRENT_USER";
    hkey_path="\\Software\\Microsoft\\Internet Explorer\\PageSetup\\";
    try{
        var RegWsh = new ActiveXObject("WScript.Shell");
        hkey_key="header";
        RegWsh.RegWrite(hkey_root+hkey_path+hkey_key,"");
        hkey_key="footer";
        RegWsh.RegWrite(hkey_root+hkey_path+hkey_key,"");
    }catch(e){}
}

function getExplorer() {
    var explorer = window.navigator.userAgent ;
    //ie 
    if (explorer.indexOf("MSIE") >= 0) {
        return "IE";
    }
    //firefox 
    else if (explorer.indexOf("Firefox") >= 0) {
        return "Firefox";
    }
    //Chrome
    else if(explorer.indexOf("Chrome") >= 0){
        return "Chrome";
    }
    //Opera
    else if(explorer.indexOf("Opera") >= 0){
        return "Opera";
    }
    //Safari
    else if(explorer.indexOf("Safari") >= 0){
        return "Safari";
    }
}

方法三

通过动态创建iframe来打印(推荐的方法),这里要注意判断iframe是否存在,防止反复使用时,iframe重复创建消耗内存

function doPrint3(){
    
    //判断iframe是否存在,不存在则创建iframe
    var iframe=document.getElementById("print-iframe");
    if(!iframe){  
            var el = document.getElementById("printcontent");
            iframe = document.createElement('IFRAME');
            var doc = null;
            iframe.setAttribute("id", "print-iframe");
            iframe.setAttribute('style', 'position:absolute;width:0px;height:0px;left:-500px;top:-500px;');
            document.body.appendChild(iframe);
            doc = iframe.contentWindow.document;
            //这里可以自定义样式
            //doc.write("<LINK rel="stylesheet" type="text/css" href="css/print.css">");
            doc.write('<div>' + el.innerHTML + '</div>');
            doc.close();
            iframe.contentWindow.focus();            
    }
    iframe.contentWindow.print();
    if (navigator.userAgent.indexOf("MSIE") > 0){
        document.body.removeChild(iframe);
    }
    
}

总结

使用方法一、二时,弊端有2个:

1)由于替换来当前页面的内容,从而当取消打印时,会使原来的页面一些form表单失效。

2)当前页面中的样式会影响到打印的内容中的样式。

所以这里推荐使用iframe来创建,并且可以自定义样式。

以上内容在谷歌浏览器下测试通过,其他浏览器未做验证。

0 条回应

必须 注册 为本站用户, 登录 后才可以发表评论!