美文网首页前端开发那些事儿
前端生成图片,利用 html2canvas 生成

前端生成图片,利用 html2canvas 生成

作者: 至远方 | 来源:发表于2020-12-04 15:48 被阅读0次

    此项目以vue为例,引用方式是

    cnpm install html2canvas -s
    // 在用到的地方引用
    import html2canvas from 'html2canvas'
    

    不是 vue 的可以直接引用 js 文件,不多说话,直接上代码(注释都在里面了)

     printSeat() {
        this.$store.commit("updatePageLoading", ++this.$store.state.pageLoading)
        // 下面是这边需求,需要对打印出来的东西做一些样式调整,写的代码,可根据自己业务需求进行修改
        document.querySelectorAll('#chartList')[0].style.top = 0;
        document.querySelectorAll('#chartList')[0].style.left = 0;
    
        try {
          document.querySelectorAll('.group-area-right')[0].style.right = '180px';
        } catch (error) {
    
        }
        try {
          document.querySelectorAll('.group-area-left')[0].style.left = '180px';
        } catch (error) {
    
        }
        try {
          document.querySelectorAll('.area-class')[0].style.left = '180px';
        } catch (error) {
    
        }
        
        // 这边就是我们的业务代码了,也可以不用 document.createElement("canvas"), 直接进行html2canvas 进行生成图片,我这边因为图片过大,生成出来的图片很模糊,就进行了处理
        let canvas2 = document.createElement("canvas");
        let _canvas = document.querySelectorAll('#seatPrint')[0];
    
        let w = parseInt(window.getComputedStyle(_canvas).width);
        let h = parseInt(window.getComputedStyle(_canvas).height);
    
        //将canvas画布放大若干倍,然后盛放在较小的容器内,就显得不模糊了
        canvas2.width = w * 1.9;
        canvas2.height = h * 1.6;
        //可以按照自己的需求,对context的参数修改,translate指的是偏移量
        let context = canvas2.getContext("2d");
        context.scale(2, 2);
        // context.translate(100, 0);
        document.querySelectorAll('#seatPrint')[0].style.transform = 'scale(.8)';
        document.querySelectorAll('#seatPrint')[0].style.marginLeft = '-10%';
        document.querySelectorAll('#seatPrint')[0].style.width = '120%';
    
        let that = this
        // { canvas: canvas2 } 不处理的话是不用穿的,直接传第一个参数就行(需要生成的dom区域)
        html2canvas(document.querySelectorAll('#seatPrint')[0], { canvas: canvas2 }).then((canvas) => {
            // canvas.toDataURL() 输出的 base64
            const blob = this.convertBase64UrlToBlob(canvas.toDataURL()); // 转成bolb
            // 下载的文件名称
            const fileName = this.$route.query.planName + '座次图'
            if (window.navigator.msSaveOrOpenBlob) {
              navigator.msSaveBlob(blob, fileName);
            } else {
              // 创建 a 标签,开始下载
              const link = document.createElement('a');
              link.href = window.URL.createObjectURL(blob);
              link.download = fileName;
              //此写法兼容可火狐浏览器
              document.body.appendChild(link);
              const evt = document.createEvent("MouseEvents");
              evt.initEvent("click", false, false);
              link.dispatchEvent(evt);
              document.body.removeChild(link);
              // 样式恢复
              setTimeout(() => {
                this.$store.commit("updatePageLoading", --this.$store.state.pageLoading) 
                // 下面注释的代码,火狐浏览器不支持(苦恼,奈何客户用的是火狐,继续采坑)
                // document.querySelectorAll('.list-box')[0].style.zoom = 1; 
                document.querySelectorAll('#seatPrint')[0].style.transform = 'scale(1)';
                document.querySelectorAll('#seatPrint')[0].style.marginLeft = 0;
                document.querySelectorAll('#seatPrint')[0].style.width = '100%';
                try {
                  document.querySelectorAll('.group-area-right')[0].style.right = '30px';
                } catch (error) {
    
                }
                try {
                  document.querySelectorAll('.group-area-left')[0].style.left = '30px';
                } catch (error) {
    
                }
                try {
                  document.querySelectorAll('.area-class')[0].style.left = '0px';
                } catch (error) {
    
                }
              }, 100)
            }
        }).catch(err => {
          this.$store.commit("updatePageLoading", --this.$store.state.pageLoading)  
        });
    
     convertBase64UrlToBlob(base64) {
          let parts = base64.split(";base64,");
          let contentType = parts[0].split(":")[1];
          let raw = window.atob(parts[1]);
          let rawLength = raw.length;
          let uInt8Array = new Uint8Array(rawLength);
          for (let i = 0; i < rawLength; i++) {
              uInt8Array[i] = raw.charCodeAt(i);
          }
          return new Blob([uInt8Array], { type: contentType });
      }
    

    在中间遇到了一个奇怪的问题,就是chrome浏览器生成图片大约要3秒钟左右,而火狐浏览器能加载一分钟,提示显示

    image

    刚开始以为打印的dom元素比较多,然后就尝试了打印部分dom,都没有问题,只要已使用外层的dom就会提示,后来我改了dom元素的层级结构,然后就快了很多,中间尝试过直接后端生成,但是我觉得前端应该也没问题,网上查了说chrome 和 火狐浏览器都挺好用的,然后就开始改层级了

    相关文章

      网友评论

        本文标题:前端生成图片,利用 html2canvas 生成

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