首页 > 前端
Html页面生成pdf下载
来源:TP课堂 时间:2022-09-18 点击:415

有的时候需要页面生成pdf,通常是页面的某个部分而不是全部,最后能够下载pdf文件。


引入js:

  <script type="text/javascript" src="https://www.jq22.com/demo/htmltopdf202104260117/js/canvas.js"></script>
  <script type="text/javascript"
    src="https://lf6-cdn-tos.bytecdntp.com/cdn/expire-1-M/jspdf/1.0.272/jspdf.min.js"></script>

功能实现:

.have_choose_box是需要生成pdf的区域。

.make_pic是触发的按钮。

upload_pdf是在服务器上保存pdf文件,最终生成一个pdf链接。


    $('.make_pic').click(function () {
      $("#mood_board .have_choose_box .item .bar").css('display', 'none');
      function aa() {
        var target = document.getElementsByClassName("have_choose_box")[0]; //避免生成的PDF页面底部出现黑色背景
        target.style.background = "#FFFFFF";

        html2canvas(target, {
          onrendered: function (canvas) {
            var contentWidth = canvas.width;
            var contentHeight = canvas.height;

            //一页pdf显示html页面生成的canvas高度;
            var pageHeight = contentWidth / 841.89 * 592.28;


            //未生成pdf的html页面高度
            var leftHeight = contentHeight;
            //页面偏移
            var position = 0;
            //a4纸的尺寸[595.28,841.89],html页面生成的canvas在pdf中图片的宽高
            //var imgWidth = 595.28;
            //var imgHeight = 592.28/contentWidth * contentHeight;
            var imgWidth = 841.89;
            var imgHeight = 841.89 / contentWidth * contentHeight;

            var pageData = canvas.toDataURL('image/jpeg', 1.0);
            //l表示横版,p:纵向 (默认纵向)
            var pdf = new jsPDF('l', 'pt', 'a4');

            //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
            //当内容未超过pdf一页显示的范围,无需分页
            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;
                position -= 595.28;
                //避免添加空白页
                if (leftHeight > 0) {
                  pdf.addPage();
                }
              }
            }

            pdf.save("mood_board.pdf");
            // 将pdf输入为base格式的字符串
            var buffer = pdf.output("datauristring")
            // 将base64格式的字符串转换为file文件
            var myfile = dataURLtoFile(buffer, "mood_board.pdf")
            name = upload_pdf(myfile)
          }
        })
      }
      aa();

    });

    //pdf文件上传
    upload_pdf = function (file) {
      var order_id = $(".order_id").val();
      var formdata = new FormData()
      formdata.append("file", file); // 文件对象
      formdata.append("order_id", order_id);
      //多个参数的情况
      // formdata.append("name", name);
      var msg = '';
      // 之后ajax传递数据
      $.ajax({
        url: "/index/mood_upload",                      //url地址
        type: 'POST',                 //上传方式
        data: formdata,                   // 上传formdata封装的数据
        dataType: 'JSON',
        cache: false,                  // 不缓存
        async: false,                   // 开启的异步 保证返回信息
        processData: false,            // jQuery不要去处理发送的数据
        contentType: false,            // jQuery不要去设置Content-Type请求头
        success: function (data) {
          if (data.status == 0) {
            //var url= data.url;
            //跳转pdf界面 uploadUrl为服务器地址
            window.open(uploadUrl + url)
          } else {
            layer.alert("文件上传失败");
          }
        },
        error: function (data) {           //失败回调
          layer.msg('数据不能为空', { icon: 5 });
          console.log(data);
        }
      });
      //返回值
      //return url;
    };
    //将base64转换为文件对象
    function dataURLtoFile(dataurl, filename) {
      var arr = dataurl.split(',');
      var mime = arr[0].match(/:(.*?);/)[1];
      var bstr = atob(arr[1]);
      var n = bstr.length;
      var u8arr = new Uint8Array(n);
      while (n--) {
        u8arr[n] = bstr.charCodeAt(n);
      }
      //转换成file对象
      return new File([u8arr], filename, { type: mime });
      //转换成成blob对象
      //return new Blob([u8arr],{type:mime});
    }