导语:

之前在项目有一个关于打印指定区域的需求,google和百度了很多文章,基本上解决方案大同小异的,这里想自己写一篇,方便以后使用。解决方法一般分为两类:vue-print-nb 和 本地下载print.js, 第一种这里就不再多讲,这里主要是介绍 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'

 }, options);

  

 if ((typeof dom) === "string") {

 this.dom = document.querySelector(dom);

 } else {

 this.isDOM(dom)

 this.dom = this.isDOM(dom) ? dom : dom.$el;

 }

  

 this.init();

};

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>html,body,div{height: auto!important;margin:0;padding:0}</style>";

 // str += "<style>html,body,div{height: auto!important;}</style>";

 return str;

 },

  

 getHtml: function () {

 var inputs = document.querySelectorAll('input');

 var textareas = document.querySelectorAll('textarea');

 var selects = document.querySelectorAll('select');

 var canvass = document.querySelectorAll('canvas');

 var isNeedRemove = document.querySelectorAll('.isNeedRemove')

 for (var k = 0; k < inputs.length; k++) {

 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)

 } else {

 inputs\[k\].setAttribute('value', inputs\[k\].value)

 }

 }

  

 for (var k2 = 0; k2 < textareas.length; k2++) {

 if (textareas\[k2\].type == 'textarea') {

 textareas\[k2\].innerHTML = textareas\[k2\].value

 }

 }

  

 for (var k3 = 0; k3 < selects.length; k3++) {

 console.log(isNeedRemove)

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

 }

 }

 }

 }

 }

 //canvass echars图表转为图片

 for (var k4 = 0; k4 < canvass.length; k4++) {

 if (isNeedRemove.length == 0) {

 var imageURL = canvass\[k4\].toDataURL("image/png");

 var img = document.createElement("img");

 img.src = imageURL;

 img.setAttribute('style', 'max-width: 100%;');

 img.className = 'isNeedRemove'

 canvass\[k4\].style.display = 'none'

 // canvass\[k4\].parentNode.style.width = '100%'

 // canvass\[k4\].parentNode.style.textAlign = 'center'

 canvass\[k4\].parentNode.insertBefore(img, canvass\[k4\].nextElementSibling);

 }

 }

 //做分页

 //

 // var pages = document.querySelectorAll('.result');

 // for (var k5 = 0; k5 < pages.length; k5++) {

 //   pages\[k5\].setAttribute('style', 'page-break-after: always');

 // }

 return this.dom.outerHTML;

 },

  
  

 writeIframe: function (content) {

 var w, doc, iframe = document.createElement('iframe'),

 f = document.body.appendChild(iframe);

 iframe.id = "myIframe";

 //iframe.style = "position:absolute;width:0;height:0;top:-10px;left:-10px;";

 iframe.setAttribute('style', 'position:absolute;width:0;height:0;top:-10px;left:-10px;');

 w = f.contentWindow || f.contentDocument;

 doc = f.contentDocument || f.contentWindow.document;

 doc.open();

 doc.write(content);

 doc.close();

 var \_this = this

 iframe.onload = function () {

 \_this.toPrint(w);

 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);

 }

 },

 isDOM: (typeof HTMLElement === 'object') ?

 function (obj) {

 return obj instanceof HTMLElement;

 } : function (obj) {

 return obj && typeof obj === 'object' && obj.nodeType === 1 && typeof obj.nodeName === 'string';

 }

};

 const MyPlugin = {}

 MyPlugin.install = function (Vue, options) {

   // 4. 添加实例方法

   Vue.prototype.$print = Print

 }

export default MyPlugin

在main.js 中 引入,注册使用就行

import print from '@/utils/print'
Vue.use(print)

组件中使用: 给需要的打印区域添加 ref="print"

<template>
    <div>
      <div ref="print">
        这是需要打印的内容
      </div>  
    </div>
</template>

<script>
    this.$print(this.$refs.print)
</script>
有时候可能有打印区域里面包含了部分你不想被打印的内容,解决方法如下所示:
方法一:添加no-print 样式
<template>
    <div>
      <div ref="print">
        这是需要打印的内容
        <div calss="no-print">这是不需要被打印的部分</div>
      </div>  
    </div>
</template>

<script>
    this.$print(this.$refs.print)
</script>
方法二:自定义类名
<template>
    <div>
      <div ref="print">
        这是需要打印的内容
        <div class="do-not-print-me-xxxx">这是不需要被打印的部分</div>
      </div>  
    </div>
</template>

<script>
    this.$print(this.$refs.print,{'no-print':'do-not-print-me-xxxx'})
</script>

墨鱼
1 声望1 粉丝

万般皆苦,唯有自渡。