Vue——printjs打印el-table,echarts等打印不全,异常解决

这篇具有很好参考价值的文章主要介绍了Vue——printjs打印el-table,echarts等打印不全,异常解决。希望对大家有所帮助。如果存在错误或未考虑完全的地方,请大家不吝赐教,您也可以点击"举报违法"按钮提交疑问。

PrintJs简单使用

PrintJs官网地址:https://printjs.crabbly.com/

1、可以从GitHub版本下载最新版本的Print.js:https://github.com/crabbly/Print.js/releases
2、npm 安装

npm install print-js --save

更多参考:https://blog.csdn.net/sunxiaoju/article/details/126284860

echarts无法打印解决

修改print.js的getHtml,增加对canvas的处理,将echarts转为图片:

 getHtml: function () {
        var inputs = document.querySelectorAll('input');
        var textareas = document.querySelectorAll('textarea');
        var selects = document.querySelectorAll('select');
        var canvass = document.querySelectorAll('canvas');

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

 		//canvass echars图表转为图片
        for (var k4 = 0; k4 < canvass.length; k4++) {
            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].parentNode.insertBefore(img,canvass[k4].nextElementSibling);
        }
    },

el-table打印不全

方法一:修改print.js的getHtml方法,增加对表格的宽度处理
getHtml: function () {
        var inputs = document.querySelectorAll('input');
        var textareas = document.querySelectorAll('textarea');
        var selects = document.querySelectorAll('select');
        let cells = document.querySelectorAll('.cell');

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

        const tableNode = document.querySelectorAll('.el-table__header,.el-table__body');
        //el-table 打印不全的问题
        for(let k6 = 0 ; k6 < tableNode.length ; k6++){
            const tableItem = tableNode[k6] ;
            tableItem.style.width = '100%';
            const  child = tableItem.childNodes;
            for (let i = 0; i < child.length; i++) {
                const  element = child[i];
                if(element.localName === 'colgroup'){
                    element.innerHTML = '';
                }
            }
        }
        //el-table 格子里面打印超过格子的问题
        for(let k7 = 0 ; k7 < cells.length ; k7 ++){
            const cell = cells[k7] ;
            cell.style.width = '100%';
            cell.removeAttribute('style')
        }

        return this.dom.outerHTML;
    },
方法二:将el-table改为table

具体实现参考:https://blog.csdn.net/admin11196/article/details/116168923

方法三:结合html2Canvas将打印的页面转为图片

这条同样可以解决echarts不能打印问题,算是万能之法了吧,相对前面几种方式赶紧这个方法最简单,打印效果也比较理想。

1、首先需要安装html2canvas 和print-js 插件并引入,配置请参考文档:https://github.com/niklasvh/html2canvas
2、写一个打印公共方法:

//html转图片打印(解决element table打印不全的问题)
import html2canvas from "html2canvas";
import printJS from "print-js";

/**
 * html转图片
 * @param printContent
 * @param callback
 */
export const html2Canvas = (printContent, callback) => {
  // 获取dom 宽度 高度
  const width = printContent.clientWidth;
  const height = printContent.clientHeight;
  // 创建一个canvas节点
  const canvas = document.createElement("canvas");

  const scale = 4; // 定义任意放大倍数,支持小数;越大,图片清晰度越高,生成图片越慢。
  canvas.width = width * scale; // 定义canvas 宽度 * 缩放
  canvas.height = height * scale; // 定义canvas高度 *缩放
  canvas.style.width = width * scale + "px";
  canvas.style.height = height * scale + "px";
  canvas.getContext("2d").scale(scale, scale); // 获取context,设置scale

  const scrollTop =
    document.documentElement.scrollTop || document.body.scrollTop; // 获取滚动轴滚动的长度
  const scrollLeft =
    document.documentElement.scrollLeft || document.body.scrollLeft; // 获取水平滚动轴的长度

  html2canvas(printContent, {
    canvas,
    backgroundColor: null,
    useCORS: true,
    windowHeight: document.body.scrollHeight,
    scrollX: -scrollLeft, // 解决水平偏移问题,防止打印的内容不全
    scrollY: -scrollTop
    //background: "#ffffff", // 一定要添加背景颜色,否则出来的图片,背景全部都是透明的
  })
    .then(canvas => {
      const url = canvas.toDataURL("image/png");
      //console.log("canvas url :" + url);
      callback({ url: url });
    })
    .catch(err => {
      console.error(err);
    });
};

/**
 * 用printJs打印图片
 * @param url
 * @param callback
 */
export const printImg = (url, callback) => {
  printJS({
    printable: url,
    type: "image",
    documentTitle: "", // 标题
    style: "@page{size:auto;margin: 1cm ;}", // 去除页眉页脚
    onStart: () => {
      console.log("打印开始");
    },
    onEnd: () => {
      console.log("打印完成");
    }
  });
};

/**
 * html转图片打印
 * @param dom
 * @param callback
 */
export const html2CanvasPrint = (dom, callback) => {
  //1、html转图片
  html2Canvas(dom, canvasRes => {
    //2、打印图片
    printImg(canvasRes.url, callback);
  });
};

3、调用方法:

html2Canvas(this.$refs.printDom, res => {
	this.printDomUrl = res.url;
	printImg(res.url, printRes => {});
});

更多内容参考:https://blog.csdn.net/weixin_40466351/article/details/115908035

注意:遇到大坑啊,html转图片的方式在windows上面打印预览没有任何问题,但是在Mac上面所有的字体间距均被放大,页面简直错的离谱啊,无奈又换回方法二,通过调整dom打印缩放解决了。

具体方法如下:

  1. 修改print.js的getHtml方法,参考方法一的内容;

  2. 在开始打印前缩小dom的尺寸;打印结束后恢复dom的原尺寸;

    print.js监听打印预览的关键代码:

const Print = function (dom, options) {
    if (!(this instanceof Print)) return new Print(dom, options);

    this.options = this.extend({
        'noPrint': '.no-print',
        onStart: function () {},//打印开始监听回调
        onEnd: function () {}//打印结束监听回调(打印预览中点击“打印”或“取消”都可以回调)
    }, options);

    if ((typeof dom) === "string") {
        this.dom = document.querySelector(dom);
    } else {
        this.isDOM(dom)
        this.dom = this.isDOM(dom) ? dom : dom.$el;
    }

    this.init();
};

toPrint: function (frameWindow) {
	let _this = this;
	try {
	    setTimeout(function () {
	        frameWindow.focus();
	        typeof _this.options.onStart === 'function' && _this.options.onStart();
	        try {
	            if (!frameWindow.document.execCommand('print', false, null)) {
	                frameWindow.print();
	            }
	        } catch (e) {
	            frameWindow.print();
	        }
	        typeof _this.options.onEnd === 'function' && _this.options.onEnd();
	        frameWindow.close();
	    }, 10);
	} catch (err) {
	    console.log('err', err);
	}
    },

核对你的print.js文件是否包含了上述监听回调的内容,没有的话自行加上。
打印过程修改dom尺寸方法:

//由于打印内容宽度过大,所以打印前先将dom缩小,打印完成之后恢复原尺寸
this.$refs.printDom.style.zoom = 0.6;

this.$print(this.$refs.printDom, {
  type: "html",
  documentTitle: "", // 标题
  style: "@page{size:auto;margin: 1cm ; size: }", // 去除页眉页脚
  onStart: () => {
    console.log("打印开始");
  },
  onEnd: () => {
    console.log("打印完成");
    this.$refs.printDom.style.zoom = 1;
  }
});

最后还需注意一个点,你的打印内容遇到分页时如果出现被截断的情况下,需要处理下,在任何你不想截断的模块中加上如下css代码即可;

//避免打印截断
page-break-inside: avoid;
page-break-after: avoid;
page-break-before: avoid;

扩展:修改打印表格样式

参考:https://blog.csdn.net/huyande123/article/details/103423362
简单总结的说下:页面打印样式缺失可能是打印时新建的一个dom对象没有将原来的页面样式传递过来,可以通过将一些相关的CSS传递到document.write()方法中的新窗口来解决这个问题。
关键代码:文章来源地址https://www.toymoban.com/news/detail-455029.html

var divToPrint = document.getElementById('box');
var htmlToPrint = '' +
    '<style type="text/css">' +
        'table {'+
        'border-right:1px solid #000;' +
        'border-bottom:1px solid #000;'+
        '}' +
        'table td{'+
            'border-left:1px solid #000;'+
            'border-top:1px solid #000'+
        '}'+
    '</style>';
htmlToPrint += divToPrint.outerHTML;
newWin = window.open("");
newWin.document.write(htmlToPrint);
newWin.print();
newWin.close();

到了这里,关于Vue——printjs打印el-table,echarts等打印不全,异常解决的文章就介绍完了。如果您还想了解更多内容,请在右上角搜索TOY模板网以前的文章或继续浏览下面的相关文章,希望大家以后多多支持TOY模板网!

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处: 如若内容造成侵权/违法违规/事实不符,请点击违法举报进行投诉反馈,一经查实,立即删除!

领支付宝红包 赞助服务器费用

相关文章

  • 【详解|彻底搞懂el-table和列表过滤】vue列表过滤和el-table的实现

    vue列表过滤 el-table的理解 先来看一段代码: chatGPT 的理解真的很6: 这段代码使用了 Element UI 的组件,创建了一个表格列组件 el-table-column,并为它设置了一些属性和插槽。 各种属性: 名称 作用 prop 指定了该列绑定的数据对象的属性名为 warehouseName label 指定了该列的列名为 “

    2024年02月11日
    浏览(44)
  • vue el-table实现动态表头

    众所周知,element-ui中有一个表格组件el-table,用于展示多条结构类似的数据。之前遇到过一个需求,要手动控制el-table的表头显示。就是假如table表格一共有10列数据,可以通过设置勾选,决定显示多少列。 为了代码的复用性,将配置页面单独抽成了组件,所以代码中会有组件

    2024年02月12日
    浏览(51)
  • vue封装el-table表格组件

    先上效果图: 本文包含了具名插槽、作用域插槽、jsx语法三种: Render.vue( 很重要,必须有 ): Table.vue 使用Table组件

    2024年02月20日
    浏览(41)
  • Vue3 el-table 单选

    解决方式:给每个表格加上唯一key值

    2024年02月11日
    浏览(52)
  • vue+el-table实现展开与折叠

    本文会提到两种实现方法,之前我使用的是第一种,后来加了固定列,发现展开与折叠失效,故而出现了第二种方法。 一、通过class名称获取节点,并对节点进行操作(该方法表格添加固定列会失效) 1.全部展开 2.全部折叠 二、通过el-table中的 toggleRowSelection方法来实现展开与

    2024年02月14日
    浏览(47)
  • vue模拟el-table演示插槽用法

    很多人知道插槽分为三种,但是实际到elementui当中为什么这么用,就一脸懵逼,接下来就跟大家聊一聊插槽在elementui中的应用,并且自己写一个类似el-table的组件 vue的slot分为三种::匿名插槽,具名插槽, 作用域插槽,主要作用:让父组件可以向子组件指定位置插入 html 结构

    2024年02月06日
    浏览(36)
  • vue el-table 多选框回填

    主要代码: 效果: html js

    2024年01月18日
    浏览(47)
  • vue+elementUI el-table实现单选

    2024年02月09日
    浏览(41)
  • vue + el-table点击表头改变其当前样式

    废话不多说,先看效果: 网上找了一大圈没有符合的,只能自己看着搞: 直接贴代码: 这种写法经使用过程中发现问题,故修改为以下:

    2024年02月13日
    浏览(39)
  • 【vue】el-table实现动态添加行和列

    实现思路: 最近遇到一个动态增加行和列的需求,本来拿到需求的时候想用el-table中自带的方法去实现的,但是经过尝试发现不能满足想要实现的需求。没办法只能在el-table的基础上自己写原生。 大概思路如下: 1.首先把table中需要动态增加的行和列分开,分别定义一个数组

    2024年02月11日
    浏览(45)

觉得文章有用就打赏一下文章作者

支付宝扫一扫打赏

博客赞助

微信扫一扫打赏

请作者喝杯咖啡吧~博客赞助

支付宝扫一扫领取红包,优惠每天领

二维码1

领取红包

二维码2

领红包