jsPDF + html2canvas,生成PDF,获取base64后转file

项目需要生成PDF,转为file上传到附件服务器,东拼西凑了下面的方法

JavaScript
/**
 * @param html { String } DOM树
 * @param isOne { Boolean }  是否为单页 默认 否(false)
 * @return 文件 {pdf格式}
 */    
setPrint(html,isOne) {
      
      let html = document.getElementById("doa_print_pdf_content");
      let contentWidth = html.clientWidth; // 获得该容器的宽
      let contentHeight = html.clientHeight; // 获得该容器的高
      let canvas = document.createElement("canvas");
      let scale = 1; // 解决清晰度问题,先放大 2倍

      canvas.width = contentWidth * scale; // 将画布宽&&高放大两倍
      canvas.height = contentHeight * scale;
      canvas.getContext("2d").scale(scale, scale);

      let opts = {
        scale: scale,
        canvas: canvas,
        width: contentWidth,
        height: contentHeight,
        useCORS: true,
      };

      return this.$html2canvas(html, opts).then((canvas) => {
        let pageData = canvas.toDataURL("image/jpeg", 1.0); // 清晰度 0 - 1
        let pdf;

        if (isOne) {
          // 单页
          console.log(contentWidth, "contentWidth");
          console.log(contentHeight, "contentHeight");

          // jspdf.js 插件对单页面的最大宽高限制 为 14400
          let limit = 14400;

          if (contentHeight > limit) {
            let contentScale = limit / contentHeight;
            contentHeight = limit;
            contentWidth = contentScale * contentWidth;
          }

          let orientation = "p";
          // 在 jspdf 源码里,如果是 orientation = 'p' 且 width > height 时, 会把 width 和 height 值交换,
          // 类似于 把 orientation 的值修改为 'l' , 反之亦同。
          if (contentWidth > contentHeight) {
            orientation = "l";
          }

          // orientation Possible values are "portrait" or "landscape" (or shortcuts "p" or "l")
          pdf = new this.$jsPDF(orientation, "pt", [contentWidth, contentHeight]); // 下载尺寸 a4 纸 比例

          // pdf.addImage(pageData, 'JPEG', 左,上,宽度,高度)设置
          pdf.addImage(pageData, "JPEG", 0, 0, contentWidth, contentHeight);
        } else {
          //一页 pdf 显示 html 页面生成的 canvas高度
          let pageHeight = (contentWidth / 552.28) * 841.89;
          //未生成 pdf 的 html页面高度
          let leftHeight = contentHeight;
          //页面偏移
          let position = 0;
          //a4纸的尺寸[595.28,841.89],html 页面生成的 canvas 在pdf中图片的宽高
          let imgWidth = 555.28;
          let imgHeight = (imgWidth / contentWidth) * contentHeight;

          pdf = new this.$jsPDF("", "pt", "a4"); // 下载尺寸 a4 纸 比例
          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
          //当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < pageHeight) {
            pdf.addImage(pageData, "JPEG", 20, 0, imgWidth, imgHeight);
          } else {
            while (leftHeight > 0) {
              pdf.addImage(pageData, "JPEG", 20, position, imgWidth, imgHeight);
              leftHeight -= pageHeight;
              position -= 841.89;
              //避免添加空白页
              if (leftHeight > 0) {
                pdf.addPage();
              }
            }
          }
        }
    //找的别的方法:pdf.output("dataurlstring").split("base64,")[1]是base64,实际上pdf.output("dataurlstring")就是base64
        let file = this.base64ConvertFile(pdf.output("dataurlstring"),"heyidan");
    //到这里转换为file文件已经全部完成


        let fileType = file.name.split(".");
        fileType = fileType[fileType.length - 1];
        let param = new FormData(); //创建form对象
        param.append("uploadfile", file, file.name); //通过append向form对象添加数据
        param.append("name", "uploadfile"); //添加form表单中其他数据
        param.append("filename", `${this.guid()}.${fileType}`); //添加form表单中其他数据
        //console.log(param.get('tweetPic')); //FormData私有类对象,访问不到,可以通过get判断值是否传进去
        let config = {
          headers: { "Content-Type": "multipart/form-data" }
        }; //添加请求头
        this.$http
          .post("mp/file/vt/upload.do", param, config)
          .then(res => {
            console.log(res);
            if (res.result == 1) {
              // this.setImg(res.path[0][0].split("|")[1], state);
              //对返回的数据进行处理
              let params = {};
              params.attUrl = res.path[0][0].split("|")[1];
              params.fileName = res.path[0][0].split("|")[0];
            }
          });
      });
    },

    //base64转file文件
    base64ConvertFile (urlData, filename) { // 64转file
      // if (typeof urlData != 'string') {
      //   this.$toast("urlData不是字符串")
      //   return;
      // }
      var arr = urlData.split(',');
      var type = arr[0].match(/:(.*?);/)[1];
      var fileExt = type.split('/')[1];
      var bstr = atob(arr[1]);
      var n = bstr.length;
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      return new File([u8arr], filename + "." + fileExt, {
        type: type
      });
    },

    guid() {
      return "xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx".replace(/[xy]/g, function(
        c
      ) {
        var r = (Math.random() * 16) | 0,
          v = c == "x" ? r : (r & 0x3) | 0x8;
        return v.toString(16);
      });
    },

 


版权声明:本文为shidaione原创文章,遵循CC 4.0 BY-SA版权协议,转载请附上原文出处链接和本声明。