这里给大家分享我在网上总结出来的一些知识,希望对大家有所帮助
网页实现打印 可以选择性的打印某一部分 的vue组件
1.引入 把print.js 下载到本地,然后放在src 下面添加文件夹里.
print.js
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 | // 打印类属性、方法定义 /* 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 >"; return str; }, getHtml: function () { var inputs = document.querySelectorAll('input'); var textareas = document.querySelectorAll('textarea'); var selects = document.querySelectorAll('select'); 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++) { 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') } } } } } // 包裹要打印的元素 // fix: https://github.com/xyl66/vuePlugs_printjs/issues/36 let outerHTML = this.wrapperRefDom(this.dom).outerHTML return outerHTML; }, // 向父级元素循环,包裹当前需要打印的元素 // 防止根级别开头的 css 选择器不生效 wrapperRefDom: function (refDom) { let prevDom = null let currDom = refDom // 判断当前元素是否在 body 中,不在文档中则直接返回该节点 if (!this.isInBody(currDom)) return currDom while (currDom) { if (prevDom) { let element = currDom.cloneNode(false) element.appendChild(prevDom) prevDom = element } else { prevDom = currDom.cloneNode(true) } currDom = currDom.parentElement } return prevDom }, 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); } }, // 检查一个元素是否是 body 元素的后代元素且非 body 元素本身 isInBody: function (node) { return (node === document.body) ? false : document.body.contains(node); }, 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 |
2.在main.js 里面引入并注册
1 2 | import Print from '@/plugs/print' Vue.use(Print) // 注册 |
3.使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 | < section ref="print"> 打印内容 < div class="no-print">不要打印我</ div > </ section > this.$print(this.$refs.print) // 使用 注意事项 需使用ref获取dom节点,若直接通过id或class获取则webpack打包部署后打印内容为空 指定不打印区域 方法一. 添加no-print样式类 < div class="no-print">不要打印我</ div > 方法二. 自定义类名 < div class="do-not-print-me-xxx">不要打印我</ div > this.$print(this.$refs.print,{'no-print':'.do-not-print-me-xxx'}) // 使用 |
4.注意事项:
-
(1) 有一页内容却打印两页有一个空白页--问题
解决:margin 影响了.查找影响的margin样式改成padding -
(2) 样式书写不能使用less 和sass 可以使用原始class
-
(3) echarts 打印不出来 --问题
隐藏echarts 把echarts 转换成图片.然后页面展示图片.图片可以进行打印进行.
1 2 | < div id="myRadarChart" :style="{width: '440px', height: '240px'}" class="myChart" v-show="false"></ div > < img :src="canvasImg" width="440" height="240"> |
1 2 3 4 5 6 7 | drawLine() { this.myRadarChart = this.$echarts.init(document.getElementById('myRadarChart')) this.myRadarChart.setOption({...}) this.canvasImg = this.myRadarChart.getConnectedDataURL({ pixelRatio: 2 }) }, |
- (4) 背景颜色不生效 -- 问题
- 需要在添加背景颜色的样式里面添加 -webkit-print-color-adjust: exact;
- 例如:
1 2 3 4 5 6 7 | .top{ background: #F1F3F9; border-radius: 10px 10px 0 0; font-size: 12px; color: #5A6173; -webkit-print-color-adjust: exact; } |
本文转载于:
https://juejin.cn/post/6844904161713078279
如果对您有所帮助,欢迎您点个关注,我会定时更新技术文档,大家一起讨论学习,一起进步。
__EOF__