打印

作者: zlf_j | 来源:发表于2020-12-13 20:22 被阅读0次

js调起打印(某个div里的内容)

vue + elementUI

  • vue
<template>
<div id="printBox">
        打印的内容
        <el-button class="noprint" @click="printing" type="primary">打印</el-button>
</div>
</template>
  • js
       printing () {
            var body=document.getElementById("printBox"); // 获取打印部分的div
            document.body.outerHTML=body.outerHTML // 打印div中的内容  outerHTML => 打印可以带上css样式
            window.print(); // js调起打印
            location.reload(); // 打印完成后,或取消打印,复原页面内容,直接刷新
        }
  • css(打印时的样式,隐藏掉打印按钮)
<style>
@media print {
        .noprint{
            display: none;
        }
    }
</style>

打印时打开一个新页面,打印后关闭

  • html
 <div id="printBox"> 
        <!--你需要打印的内容-->
 </div>
  • js
var printBox = document.getElementById('printBox'); //获取需要打印的内容
var newWin = window.open(window.document.URL); //新打开一个标签页,这样不会影响现使用的页面
var newContent =printBox.innerHTML;
newWin.document.body.innerHTML = newContent; //将打印的部分赋值给新打开的标签页
newWin.print();//执行打印
newWin.close();//关闭打印窗口

https://blog.csdn.net/wwwwerewrew/article/details/100137746

A4纸打印

@media print { // 打印时执行
        @page { // 设置打印样式
            size: A4; // A4
            size: portrait; // 纵向打印
            margin: 0; // 边距设置,自定义
        }
        // 隐藏滚动条
        ::-webkit-scrollbar {display:none} 
    }

https://www.softwhy.com/article-5613-1.html

  • 打印的背景颜色不展示
-webkit-print-color-adjust: exact; // 加给打印的div即可

https://www.cnblogs.com/sese/p/9057732.html

Safari 兼容

插件:https://www.cnblogs.com/coderwhytop/p/14462603.html

问题1:Safari打印一次后,不能再次打印

原因:document.body.removeChild(frame1) 删除元素太快
解决办法:加setTimeout,延时处理
前提:使用print.js打印
https://cloud.tencent.com/developer/ask/208425

问题2:Safari 按794px×1123px写的页面,打印A4纸,一小部分不展示

临时解决办法:判断Mac系统,给打印的部分做了缩放

使用流程:

1、main.js

import Print from '@/utils/print.js' // 打印
Vue.use(Print)

2、js 调用打印

   let body = document.getElementById("print");
   document.body.outerHTML = body.outerHTML
   that.$print(that.$refs.print)

3、css(为了修复问题2,看情况使用,仅供参考)

  • 动态加class
<div :class="isMac? 'is_mac': ''"></div>
  • css只针对Mac缩放
    .is_mac {
          transform: scale(0.97);  // 缩放比例
          transform-origin: 0 bottom; // 缩放位置
    }
  • js判断系统是否是Mac
data() {
   return {
          isMac: false
   }
},
created() {
      this.isMac = /macintosh|mac os x/i.test(navigator.userAgent)
}

https://blog.csdn.net/jingtian678/article/details/86378694/

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

        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 _this = this
        if (/macintosh|mac os x/i.test(navigator.userAgent) || navigator.userAgent.toLowerCase().indexOf('micromessenger') !== -1) { // Mac或企业微信
            var frame = this.appendFrame(content);
            _this.macPrint(frame)
        } else {
            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();
            iframe.onload = function() {
                _this.toPrint(w);
                setTimeout(function() {
                    document.body.removeChild(iframe)
                }, 100)
            }
        }
    },
    // mac 创建打印元素
    appendFrame: function(content) {
        var frame1 = document.createElement('iframe');
        frame1.name = "frame3";
        frame1.style.position = "absolute";
        frame1.style.top = "-1000000px";
        document.body.appendChild(frame1);

        var frameDoc = frame1.contentWindow ? frame1.contentWindow : frame1.contentDocument.document ? frame1.contentDocument.document : frame1.contentDocument;
        frameDoc.document.open();
        frameDoc.document.write(content);
        frameDoc.document.close();

        return frame1;
    },

    toPrint: function(frameWindow) {
        try {
            setTimeout(function() {
                frameWindow.focus();
                try {
                    if (!frameWindow.document.execCommand('print', false, null)) {
                        frameWindow.print();
                        location.reload(); // 刷新页面
                    }
                } catch (e) {
                    frameWindow.print();
                    location.reload(); // 刷新页面
                }
                frameWindow.close();
                location.reload(); // 刷新页面
            }, 10);
        } catch (err) {
            console.log('err', err);
        }
    },
    // Safari打印兼容
    macPrint: function(frame) {
        // Safari
        if (!window.onafterprint) {
            // emulate onbeforeprint/onafterprint events
            var mediaQueryCallback = function(mql) {
                if (!mql.matches && frame) {
                    setTimeout(function() { // 延时,解决打印自动关闭问题
                        document.body.removeChild(frame);
                        location.reload(); // 刷新页面
                    }, 200)
                }
            };
            var mediaQueryList = window.frames[frame.name].matchMedia('print');
            mediaQueryList.addListener(mediaQueryCallback);

            // the code below will trigger a cleanup in case a user hits Cancel button
            // in that Safari's new additional print confirmation dialog
            window.frames[frame.name].focus();
            window.frames[frame.name].onfocus = function() {
                return mediaQueryCallback(mediaQueryList);
            };
        }

        window.frames[frame.name].print();

        return false;
    },
    // 检查一个元素是否是 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

相关文章

网友评论

      本文标题:打印

      本文链接:https://www.haomeiwen.com/subject/ivbpgktx.html