vue,打印案例window.print()的完美实现
实现思路:通过复制原⽹页源码,然后在iframe⾥重新排版(可以按⾃⼰想要的来排版),最后iframe的contentDocument对象调⽤window.print()即可。
⽹页效果图:
调⽤window.print()打印的效果:
在main.js中引⼊
import print from'@/utils/open/print'
Vue.use(print)
vue⽂件中使⽤
<!-- html -->
<template>
<div ref="printDom1" class="wrapper">
<div class="print-btn no-print" @click="onPrint">打印</div>
<!-- .... -->
</div>
</template>
// js
export default{
name:'Print',
methods:{
/**
* 打印
*/
onPrint(){
this.$print(this.$refs.printDom1)
}
}
}
print.js 源码:
// 打印类属性、⽅法定义
/* eslint-disable */
const Print=function(dom, options){
options = options ||{}
if(!(this instanceof Print))return new Print(dom, options);
styleStr:'',
setDomHeightArr:[],// 需要动态获取并设置⾼度的元素
echartDomArr:[],// echart dom
printBeforeFn:null,// 打印前回调
printDoneCallBack:null// 打印后回调
}
for(const key f){
if(key && options.hasOwnProperty(key)){
}
}
// debugger
if((typeof dom)==="string"){
this.dom = document.querySelector(dom);
}else{
this.dom =this.isDOM(dom)? dom : dom.$el;
}
f.setDomHeightArr &&f.setDomHeightArr.length){ this.f.setDomHeightArr);
}
this.init();
};
Print.prototype ={
/**
* 初始化
*/
init:function(){
var content =Style()+Html();
this.writeIframe(content);
},
/**
* 配置属性扩展
* @param {Object} obj
* @param {Object} obj2
*/
extendOptions:function(obj, obj2){
htmlradio的text出不来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>.no-print{display:none;}${f.styleStr}</style>`;
return str;
},
// 表单赋值
getHtml:function(){
var inputs = document.querySelectorAll('input');
var textareas = document.querySelectorAll('textarea');
var selects = document.querySelectorAll('select');
// debugger
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')
}
}
}
}
}
return this.dom.outerHTML;
},
/**
创建iframe
*/
writeIframe:function(content){
// ⽅法⼆:
var w, doc, iframe = ateElement('iframe'),
f = document.body.appendChild(iframe);
console.log('f', f);
iframe.id ="myIframe";
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
// 弹出前,回调
if(_f.printBeforeFn){
_f.printBeforeFn({ doc })
}
_this.drawEchartImg(doc).then(()=>{
_Print(w);
setTimeout(function(){
veChild(iframe)
veChild(iframe)
// 弹出后,回调
if(_f.printDoneCallBack){
_f.printDoneCallBack()
}
},100)
})
}
},
/**
* 项⽬⽤到echarts,需要获取图⽚,来打印
* @param {Object} doc iframe window
*/
drawEchartImg(doc){
return new Promise((resolve, reject)=>{
f.echartDomArr &&f.echartDomArr.length >0){
const dom = doc.querySelector('#'+ e.$el.id)
const img =new Image()
const w = dom.offsetWidth +'px'
const H= dom.offsetHeight +'px'
img.style.width = w
img.style.height =H
img.src = e.imgSrc
dom.innerHTML =''
dom.appendChild(img)
})
}
resolve()
})
},
/**
打印
*/
toPrint:function(frameWindow){
try{
setTimeout(function(){
frameWindow.focus();
try{
if(!Command('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'&& deType ===1&&deName ==='string';
},
/**
* 设置指定dom元素⾼度,通过获取该dom元素现有⾼度,并设置
* @param {Array} arr
*/
setDomHeight(arr){
if(arr && arr.length){
arr.forEach(name =>{
const domArr = document.querySelectorAll(name);
const domArr = document.querySelectorAll(name);
// debugger
domArr.forEach(dom =>{
dom.style.height = dom.offsetHeight +'px';
})
})
}
}
};
const MyPlugin ={}
MyPlugin.install=function(Vue, options){
// 4. 添加实例⽅法
Vue.prototype.$print = Print
};
export default MyPlugin
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系QQ:729038198,我们将在24小时内删除。
发表评论