vue将html页面生成pdf、通过html2canvas、jsPdf.debug将html页面生成pdf

首先下载html2canvas.js和jsPdf.debug.js两个js文件

html2canvas:http://html2canvas.hertzen.com/

jsPdf.debug:https://parall.ax/products/jspdf

html

<div id="host_file">
        <div class="host_file_top_title_box">
            <p class="host_file_top_title">手机号 “xxxx” 证明文件</p>
            <div class="wide"></div>
            <div class="fine"></div>
        </div>
        <div class="host_file_prove">兹证明机主 <span class="host_file_phone">17012344321</span> xxxxxxxx实名认证,特此证明!</div>
        <div class="table_one_title">服务信息</div>
        <table>
            <tr>
                <td>手机号</td>
                <td>17012344321</td>
            </tr>
            <tr>
                <td>姓名</td>
                <td>xxx</td>
            </tr>
            <tr>
                <td>身份类型</td>
                <td>身份证</td>
            </tr>
            <tr>
                <td>证件号</td>
                <td>362202xxxxxxxxxxx</td>
            </tr>
            <tr>
                <td>实名制信息</td>
                <td>已审核</td>
            </tr>
            <tr>
                <td>服务状态</td>
                <td>正常</td>
            </tr>
            <tr>
                <td>入网时间</td>
                <td>2021-08-12</td>
            </tr>
            <tr>
                <td>到期时间</td>
                <td>2021-08-15</td>
            </tr>
        </table>
        <div class="table_one_title">运营商资料</div>
        <table>
            <tr>
                <td>运营商</td>
                <td>xxxxxxxxx有限公司</td>
            </tr>
            <tr>
                <td>许可编号</td>
                <td>中华人民共和国信息和产业化部颁发的增值电信业务经营许可证 编号:xx-123456</td>
            </tr>
            <tr>
                <td>客服电话</td>
                <td>400 888 4333</td>
            </tr>
        </table>
        <div class="host_file_footer">
            <div></div>
            <div class="host_file_footer_info">
                <p>xxxxxx有限公司</p>
                <p>http://www.xxxx.com.cn/</p>
                <p>2021年8月10日</p>
                <img class="host_file_yz" id="yzimg" src="./images/yz.png" alt="" />
            </div>
        </div>
        <div class="down_load" @click="renderPdf">下载</div>
</div>

js

<script src="./js/html2canvas.js"></script>
<script src="./js/jsPdf.debug.js"></script>
<script src="./js/vue.min.js"></script>
<script>
  new Vue({
    el: "#host_file",
    data() {
      return {

      }
    },
  methods: {

  // 下载
  renderPdf(){
    var down_load_dom=document.getElementById(moveDiv)
    moveDiv.style='display:none';
    var pdfContent = document.getElementById("host_file");
    var width = pdfContent.offsetWidth; //获取dom 宽度
    var height = pdfContent.offsetHeight; //获取dom 高度
    var canvas = document.createElement("canvas"); //创建一个canvas节点
    var scale = 1; //定义任意放大倍数 支持小数,越大越清晰
    var offsetTop = pdfContent.offsetTop;
    var rect = pdfContent.getBoundingClientRect();//获取元素相对于视察的偏移量
    canvas.width = width * scale; //定义canvas 宽度 * 缩放
    canvas.height = (height + offsetTop) * scale; //定义canvas(高度 +偏移量 )*缩放
    var content = canvas.getContext("2d");
    content.scale(scale, scale); //获取context,设置scale
    content.translate(-rect.left, -rect.top);//设置context位置,值为相对于视窗的偏移量负值,让图片复位
    var opts = {
      background: "#fff",
      scale: scale, // 添加的scale 参数
      canvas: canvas, //自定义 canvas
      // logging: true, //日志开关,便于查看html2canvas的内部执行流程
      width: width, //dom 原始宽度
      height: height,
      useCORS: true, // 【重要】开启跨域配置
      allowTaint: true,
      taintTest: false
    };
    html2canvas(pdfContent,opts ).then(function (canvas) {
      downloadCanvasWithMargin(canvas);
    })
    //-----------------------
    function downloadCanvasWithMargin(canvas){
      //关闭锯齿
      var context = canvas.getContext('2d');
      context.mozImageSmoothingEnabled = false;
      context.webkitImageSmoothingEnabled = false;
      context.msImageSmoothingEnabled = false;
      context.imageSmoothingEnabled = false;

      var img = document.getElementById("yzimg");
      img.crossOrigin = 'anonymous';

      let contentWidth = canvas.width;
      let contentHeight = canvas.height;
      //一页pdf显示html页面生成的canvas高度;
      let pageHeight = contentWidth / 595.28 * 841.89;
      //未生成pdf的html页面高度
      let leftHeight = contentHeight;
      let cutStartHeight = 0;
      let canvasArr = [];
      if(leftHeight > pageHeight) {
        while (leftHeight > 0) {
          //复制出(0, cutStartHeight)开始,contentWidth宽和pageHeight高的图片
          let cutImage = context.getImageData(0, cutStartHeight, contentWidth, pageHeight);
          //从图像底部开始校验颜色,直到验证到以白色结尾才开始切图像
          let moveUpPx = 0; //上移px数
          let totalLength = cutImage.data.length;
          let lineLength = 4 * contentWidth * 1; //一行的data容量
          let leftLength = totalLength - lineLength;
          let rightLength = totalLength;
          let circle = 0; //循环次数
          let pointRatio = 0.98; //一行给定颜色的占比系数
          let pointRatioNum = contentWidth * pointRatio;
          while( circle === moveUpPx ){
            circle ++;
            let ignorePoint = 0;
            for(let i = leftLength; i< rightLength ; i+=4){
              if(cutImage.data[i] === 255 || cutImage.data[i] === 251){
                if(cutImage.data[i] === cutImage.data[i+1] && cutImage.data[i] === cutImage.data[i+2]){
                  ignorePoint++;
                }
              }
            }
            if(ignorePoint < pointRatioNum){
              leftLength -= lineLength;
              rightLength -= lineLength;
              moveUpPx ++;
            }
          }
          if(moveUpPx > 0){
            cutImage = context.getImageData(0, cutStartHeight, contentWidth, pageHeight - moveUpPx);
          }
          leftHeight -= pageHeight - moveUpPx;
          cutStartHeight += pageHeight - moveUpPx;
          //创建新图片
          let nCanvas = document.createElement("canvas"); //创建一个canvas节点
          nCanvas.width = canvas.width;
          nCanvas.height = pageHeight - moveUpPx;
          let nContext = nCanvas.getContext("2d");
          nContext.mozImageSmoothingEnabled = false;
          nContext.webkitImageSmoothingEnabled = false;
          nContext.msImageSmoothingEnabled = false;
          nContext.imageSmoothingEnabled = false;
          nContext.putImageData(cutImage, 0, 0)
          canvasArr.push(nCanvas);
        }
      }else{
        canvasArr.push(canvas);
      }
      //处理尾页图片透明背景
      let lastCanvas = canvasArr[canvasArr.length - 1];
      let ctx = lastCanvas.getContext("2d");
      // 将canvas的透明背景设置成白色--解决translate后便黑色背景的问题
      let imageData = ctx.getImageData(0, 0, lastCanvas.width, lastCanvas.height);
      for(var i = 0; i < imageData.data.length; i += 4) {
        // 当该像素是透明的,则设置成白色
        if(imageData.data[i + 3] === 0) {
          imageData.data[i] = 255;
          imageData.data[i + 1] = 255;
          imageData.data[i + 2] = 255;
          mageData.data[i + 3] = 255;
        }
      }
      ctx.putImageData(imageData, 0, 0);
      var pdf = new jsPDF('', 'pt', 'a4');
      let leftMargin = 20;
      let topMargin = 20;
      let a4Width = 595.28;
      let a4Height = 841.89;
      let imgWidth = a4Width - leftMargin * 2;
      let imgHeight = a4Height - 2 * topMargin;
      for(let i =0; i < canvasArr.length; i++){
        let curCanvas = canvasArr[i];
        let pageData = curCanvas.toDataURL('images/jpeg', 1.0);
        //小于切分的高度,要换算比例高
        if(curCanvas.height < pageHeight){
          let ratioHeight = imgWidth / curCanvas.width * curCanvas.height;
          pdf.addImage(pageData, 'JPEG', leftMargin, topMargin, imgWidth, ratioHeight);
        }else{
          pdf.addImage(pageData, 'JPEG', leftMargin, topMargin, imgWidth, imgHeight);
        }
        if(i < (canvasArr.length-1)){
          pdf.addPage();
        }
      }
        pdf.save('load' +'.pdf');
      }
      moveDiv.style='display:block'; //
    }
  },
  created() {

  },
  mounted() {

  }
})
</script>


 

posted @ 2021-08-31 10:51  eternityQSL  阅读(249)  评论(0编辑  收藏  举报