vue中使用print.js实现页面打印并增加水印

avatar
作者
猴君
阅读量:0

1.安装print.js

npm install print-js --save 

2.在main.js文件中引入并注册(我使用的是print.js的源码文件,并且做了一修改)

//引入 import Print from './utils/print'  //注册 Vue.use(Print); //注册 

3.在页面中使用

<template> <div class="detailsPrint"> 	 <div class="move" ref="pdfContent" id="pdfContent"> 	 	需要打印的内容  	 </div> 	  <el-button type="primary" @click="printPDF">打 印</el-button>  </div> </template>  <script> export default {   name: "",    data() {     return {     };   },   methods: {     // 打印PDF     printPDF() {       this.$nextTick(() => {           this.$print(this.$refs.pdfContent, {             watermark: {               companyName: '公司名称',               name: '姓名',               date: '2024-08-01',             }       });     }   }, }; </script> <style scoped> //我希望打印出来的格式是A4纸的格式 @media print {   @page {     size: B5(JIS);     margin: 10mm 16mm;     margin-top: 8mm;     margin-bottom: 8mm;   } } </style> 

4.在utils下新增print.js

/* eslint-disable */ const Print = function (dom, options) {   if (!(this instanceof Print)) return new Print(dom, options);    this.options = this.extend({     'noPrint': '.no-print',     'watermark': {} // 接受单个水印数据对象   }, options);    if ((typeof dom) === "string") {     this.dom = document.querySelector(dom);   } else {     this.dom = dom;   }   setTimeout(() => {     this.init();   }, 2000); };  Print.prototype = {   init: function () {     var content = this.getStyle() + this.getHtml();     this.writeIframe(content);   },    extend: function (obj, obj2) {     for (var k in obj2) {       obj[k] = obj2[k];     }     return obj;   },    getStyle: function () {     var str = "",       styles = document.querySelectorAll('style,link');     for (var i = 0; i < styles.length; i++) {       str += styles[i].outerHTML;     }     str += "<style>" + (this.options.noPrint ? this.options.noPrint : '.no-print') + "{display:none;}</style>";      str += `       <style>         .watermark {           position: absolute;           top: 0;           left: 0;           width: 100%;           height: 100%;           opacity: 0.2;           pointer-events: none;         }         .watermark-content {           color:rgba(0,0,0,0.4)           text-align: center;           transform: rotate(-45deg);           font-size: 24px;         }          /* 打印样式 */         @media print {           body, html {             width: 100%;             height: 100%;             margin: 0;             padding: 0;           }           .watermark {             opacity: 0.2;             pointer-events: none;             position: fixed; /* 修正水印固定位置 */           }           .watermark-content {             text-align: center;             transform: rotate(-45deg);             font-size: 24px;              color:rgba(0,0,0,0.4)           }           /* 隐藏不需要打印的内容 */           ${this.options.noPrint} {             display: none !important;           }           /* 设置A4纸大小和页边距 */           @page {             size: B5(JIS);             margin: 10mm 16mm;             margin-top: 8mm;             margin-bottom: 8mm;           }         }       </style>     `;      return str;   },    getHtml: function () {     var inputs = document.querySelectorAll('input');     var textareas = document.querySelectorAll('textarea');     var selects = document.querySelectorAll('select');      for (var k in inputs) {       if (inputs[k].type == "checkbox" || inputs[k].type == "radio") {         if (inputs[k].checked == true) {           inputs[k].setAttribute('checked', "checked")         } else {           inputs[k].removeAttribute('checked')         }       } else if (inputs[k].type == "text") {         inputs[k].setAttribute('value', inputs[k].value)       }     }      for (var k2 in textareas) {       if (textareas[k2].type == 'textarea') {         textareas[k2].innerHTML = textareas[k2].value       }     }      for (var k3 in selects) {       if (selects[k3].type == 'select-one') {         var child = selects[k3].children;         for (var i in child) {           if (child[i].tagName == 'OPTION') {             if (child[i].selected == true) {               child[i].setAttribute('selected', "selected")             } else {               child[i].removeAttribute('selected')             }           }         }       }     }      // 使用传递的单个水印数据对象生成多个随机位置的水印     var watermarkHtml = '';     var numWatermarks = 12; // 生成的水印数量     var leftStart = -50; // 修改此处,从最左边开始的起始位置(百分比)     var leftEnd = 95; // 最右边的结束位置(百分比)     var topPositions = ['20%', '40%', '60%', '80%']; // 垂直方向的位置      var step = (leftEnd - leftStart) / (numWatermarks - 1); // 计算步长      for (var i = 0; i < numWatermarks; i++) {       var leftPosition = `${leftStart + i * step}%`;       var topPosition = topPositions[i % topPositions.length];              watermarkHtml += `          <div class="watermark" style="top: ${topPosition}; left: ${leftPosition};">            <div class="watermark-content">              <div> ${this.options.watermark.companyName}</div>              <div> ${this.options.watermark.name}</div>              <div> ${this.options.watermark.date}</div>            </div>          </div>        `;     }      return this.dom.outerHTML + watermarkHtml;   },    writeIframe: function (content) {     var iframe = document.createElement('iframe');     iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";     document.body.appendChild(iframe);      var doc = iframe.contentDocument || iframe.contentWindow.document;     doc.open();     doc.write(content);     doc.close();      this.toPrint(iframe.contentWindow);      setTimeout(function () {       document.body.removeChild(iframe);     }, 100);   },    toPrint: function (frameWindow) {     try {       setTimeout(function () {         frameWindow.focus();         try {           if (!frameWindow.document.execCommand('print', false, null)) {             frameWindow.print();           }         } catch (e) {           frameWindow.print();         }         frameWindow.close();       }, 10);     } catch (err) {       console.log('err', err);     }   } };  const MyPlugin = {}; MyPlugin.install = function (Vue, options) {   Vue.prototype.$print = Print; };  export default MyPlugin;  

广告一刻

为您即时展示最新活动产品广告消息,让您随时掌握产品活动新动态!