当前位置: > > > JS - PDF文件生成库jsPDF使用详解5(将html页面导出为pdf)

JS - PDF文件生成库jsPDF使用详解5(将html页面导出为pdf)

六、将 html 页面导出为 pdf

1,将页面上的指定元素导出成 pdf

(1)下面样例代码中,我们页面上有一个 ul 列表。当页面打开时,自定将这个 ul 列表转换成 pdf 并导出。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="jquery-3.1.1.js" charset="utf-8"></script>
    <script src="jspdf.min.js" charset="utf-8"></script>
    <script type="text/javascript">
      //页面初始化
      function init() {
        var doc = new jsPDF();

        //自定义渲染器(决定哪些元素需要渲染)
        var specialElementHandlers = {
            '#editor': function(element, renderer){
                return true;
            }
        };

        //设置边距(pdf文档中)
        var margins = {
          top: 20,
          bottom: 60,
          left: 20,
          width: 522
        };

        //获取指定html页面元素来生成pdf文件
        doc.fromHTML($('ul').get(0),
                      margins.left, //内容起点的x坐标
                      margins.top, //内容起点的y坐标
                      {
                        'width': margins.width, //内容在pdf里的最大宽度
                        'elementHandlers': specialElementHandlers
                      },
                      function (dispose) {
                        doc.save('Test.pdf');
                      },
                      margins);
      }
    </script>
  </head>
  <body onload="init()">
    <ul>
      <li>welcome to hangge.com</li>
      <li>welcome to hangge.com</li>
      <li>welcome to hangge.com</li>
    </ul>
  </body>
</html>

(2)生成的 pdf 内容如下:

2,将整个页面导出成 pdf

如果想要将整个 html 页面的所有元素都导出,只需修改一行代码。
//......

//将整个html页面导出生成pdf文件
doc.fromHTML($('body').get(0),
              margins.left, //内容起点的x坐标
              margins.top, //内容起点的y坐标

//.......

附:结合 html2canvas 实现 html 页面导出成 pdf(支持多页)

    当 html 页面内容比较复杂时,我们使用上面的方式导出后会发现里面内容格式都发生了变化。如果想让 pdf 内容结果与原页面一致,我们可以借助 html2canvas 对整个网页或局部内容进行截图,然后再将该截图导出成 pdf
注意:这里所说的截图并不是真的截图,而是通过遍历页面 DOM 结构,收集所有元素信息及相应样式,渲染出 canvas image。然后我们使用这个 canvas image 导出 pdf

1,html2canvas 配置

(1)首先我们到其官网地址将 html2canvas.js 下载到我们的项目中来。

(2)然后在页面中将其引用进来即可。
<script src="html2canvas.js" charset="utf-8"></script>

2,生成单页的 pdf

(1)如果网页内容比较少,刚好一个 pdf 页面就可以显示全的话,那么实现起来比较简单。样例代码如下:
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="jspdf.min.js" charset="utf-8"></script>
    <script src="html2canvas.js" charset="utf-8"></script>
    <script type="text/javascript">
      //页面初始化
      function init() {
        //将整个页面转成canvas
        html2canvas(document.body).then(canvas => {
            //返回图片dataURL,参数:图片格式和清晰度(0-1)
            var pageData = canvas.toDataURL('image/jpeg', 1.0);
            //方向默认竖直,尺寸ponits,格式a4[595.28,841.89]
            var doc = new jsPDF('', 'pt', 'a4');
            //addImage后两个参数控制添加图片的尺寸,此处将页面高度按照a4纸宽高比列进行压缩
            doc.addImage(pageData, 'JPEG', 0, 0, 595.28, 592.28/canvas.width * canvas.height );
            doc.save('Test.pdf');
        });
      }
    </script>
  </head>
  <body onload="init()">
    <h2>条目1</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目2</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目3</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目4</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
  </body>
</html>

(2)导出结果如下:

3,生成多页的 pdf(自动分页)

(1)如果网页内容比较多,只导出单页的 pdf 的话,那么多余的部分就会被自动截断无法显示。这就需要将内容自动拆分成多页导出。
(2)而实现内容分页的方法比较取巧。我们不必针对每页内容专门生成一个 canvas,而是统一都使用一个完整页面的 canvas。即每一页 pdf 上显示的图片其实是相同的,只不过我们通过调整图片的位置,让每一页显示它需要显示的部分,从而产生了分页效果。
<!DOCTYPE html>
<html>
  <head>
    <meta charset="utf-8">
    <title></title>
    <script src="jspdf.min.js" charset="utf-8"></script>
    <script src="html2canvas.js" charset="utf-8"></script>
    <script type="text/javascript">
      //页面初始化
      function init() {
        //将整个页面转成canvas
        html2canvas(document.body).then(canvas => {
          var contentWidth = canvas.width;
          var contentHeight = canvas.height;

          //一页pdf显示html页面生成的canvas高度;
          var pageHeight = contentWidth / 592.28 * 841.89;
          //未生成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 pageData = canvas.toDataURL('image/jpeg', 1.0);

          var doc = new jsPDF('', 'pt', 'a4');

          //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
          //当内容未超过pdf一页显示的范围,无需分页
          if (leftHeight < pageHeight) {
            doc.addImage(pageData, 'JPEG', 0, 0, imgWidth, imgHeight );
          } else {
            while(leftHeight > 0) {
                doc.addImage(pageData, 'JPEG', 0, position, imgWidth, imgHeight)
                leftHeight -= pageHeight;
                position -= 841.89;
                //避免添加空白页
                if(leftHeight > 0) {
                  doc.addPage();
                }
            }
          }

          doc.save('Test.pdf');
        });
      }
    </script>
  </head>
  <body onload="init()">
    <h2>条目1</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目2</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目3</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目4</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目5</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目6</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目7</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
    <h2>条目8</h2>
    <p>
        欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
    </p>
    <img src="./images/img1.jpg">
  </body>
</html>

(3)导出结果如下:

4,设置左右边距

(1)如果觉得导出的 pdf 中内容紧贴着左侧不好看,想要在左右两边留个边距,只需参考如下高亮部分进行修改即可。
<script type="text/javascript">
  //页面初始化
  function init() {
    //将整个页面转成canvas
    html2canvas(document.body).then(canvas => {
      var contentWidth = canvas.width;
      var contentHeight = canvas.height;

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

      var pageData = canvas.toDataURL('image/jpeg', 1.0);

      var doc = new jsPDF('', 'pt', 'a4');

      //有两个高度需要区分,一个是html页面的实际高度,和生成pdf的页面高度(841.89)
      //当内容未超过pdf一页显示的范围,无需分页
      if (leftHeight < pageHeight) {
        doc.addImage(pageData, 'JPEG', 20, 0, imgWidth, imgHeight );  //左右边距20
      } else {
        while(leftHeight > 0) {
            doc.addImage(pageData, 'JPEG', 20, position, imgWidth, imgHeight) //左右边距20
            leftHeight -= pageHeight;
            position -= 841.89;
            //避免添加空白页
            if(leftHeight > 0) {
              doc.addPage();
            }
        }
      }

      doc.save('Test.pdf');
    });
  }
</script>

(2)导出结果如下:
评论0