实现将网页html元素保存为图片

前言

本人是前端菜鸟一枚,写这个文章的目的是为纯粹是为了以后遇到同样的问题后能粘贴复制,毕竟为了实现这个功能到处看网上大佬的文章,还有leader帮助才能把这个功能完成。如果能帮助到有需要的人那我很开心,因为我很多问题都是靠网上的大佬分享的文章解决的。文字功底有限,直接开撸。

//获取canvas配置项
    getCanvasOption(shareContent){
      let canvasEle = document.querySelector('canvas');
      if(canvasEle){
        document.getElementById('dialog').removeChild(canvasEle)
      }
      let width = shareContent.offsetWidth; //获取dom 宽度
      let height = shareContent.offsetHeight; //获取dom 高度
      let canvas = document.createElement("canvas"); //创建一个canvas节点
      let scale = 2; //定义任意放大倍数 支持小数

      canvas.getContext("2d").scale(scale, scale); //获取context,设置scale 
      canvas.width = width * scale; //定义canvas 宽度 * 缩放
      canvas.height = height * scale; //定义canvas高度 *缩放

      canvas.style.cssText = 'width: '+ width +'px; height: '+ height +'px';
      let opts = {
          scale: scale, // 添加的scale 参数
          canvas: canvas, //自定义 canvas
          // logging: true, //日志开关,便于查看html2canvas的内部执行流程
          width: width, //dom 原始宽度
          height: height,
          useCORS: true // 【重要】开启跨域配置
      };
      return opts;
    },

     downloadFile(content, fileName) { //下载base64图片
      let base64ToBlob = function(code) {
        let parts = code.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
        });
      };
      let aLink = document.createElement('a');
      let blob = base64ToBlob(content); //new Blob([content]);
      let evt = document.createEvent("HTMLEvents");
      evt.initEvent("click", true, true); //initEvent 不加后两个参数在FF下会报错  事件类型,是否冒泡,是否阻止浏览器的默认行为
      aLink.download = fileName;
      aLink.href = URL.createObjectURL(blob);
      aLink.click();
    },

    //下载图片
    downLoadPic() {     
      let shareContent = document.getElementById('cert');//需要截图的包裹的(原生的)DOM 对象
      let opts = this.getCanvasOption(shareContent);
      this.html2canvas(shareContent,opts).then((canvas) =>{
        // document.getElementById('dialog').appendChild(canvas);
        let context = canvas.getContext('2d');
        // 【重要】关闭抗锯齿
        context.mozImageSmoothingEnabled = false;
        context.webkitImageSmoothingEnabled = false;
        context.msImageSmoothingEnabled = false;
        context.imageSmoothingEnabled = false;
        let MIME_TYPE = "image/png";
        let imgURL = canvas.toDataURL(MIME_TYPE);
        this.downloadFile(imgURL,'文件名')
      });
    },

    //下载pdf
    downLoadPdf() {
      let shareContent = document.getElementById('cert');//需要截图的包裹的(原生的)DOM 对象
      let opts = this.getCanvasOption(shareContent);
      this.html2canvas(shareContent,opts).then((canvas) =>{
        let contentWidth = canvas.width
        let contentHeight = canvas.height
        let pageHeight = contentWidth / 592.28 * 841.89
        let leftHeight = contentHeight
        let position = 0
        let imgWidth = 595.28
        let imgHeight = 592.28 / contentWidth * contentHeight
        let pageData = canvas.toDataURL('image/jpeg', 1.0)
        let PDF = new this.JsPDF('', 'pt', 'a4')
        if (leftHeight < pageHeight) {
          PDF.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight)
        } else {
          while (leftHeight > 0) {
            PDF.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
            leftHeight -= pageHeight
            position -= 841.89
            if (leftHeight > 0) {
              PDF.addPage()
            }
          }
        }
        PDF.save('文件名' + '.pdf')
      });
    },
  },

  mounted(){
  //此项目是服务端渲染故,因为引入的中两个包里面有window,故需在页面加载后再调用这两个包
    import('html2canvas').then((html2canvas)=>{
      this.html2canvas = html2canvas.default;
    });
    import('jspdf').then((JsPDF)=>{
      this.JsPDF = JsPDF.default;
    });
  }

此功能是在vue服务端渲染nuxt下实现的,实现这个在代码编写的时候特别要注意this的指向问题,我实习这个功能的过程中就因为this指向问题栽了坑,在method方法里面嵌套的回调最好是用箭头函数。不足之处,欢迎指正。

参考文章

https://segmentfault.com/a/1190000011478657

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值