六、将 html 页面导出为 pdf

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

(1)下面样例代码中,我们页面上有一个 ul 列表。当页面打开时,自定将这个 ul 列表转换成 pdf 并导出。
<!DOCTYPE html>
    <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()">
      <li>welcome to hangge.com</li>
      <li>welcome to hangge.com</li>
      <li>welcome to hangge.com</li>
  </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 下载到我们的项目中来。
  • 官网地址:http://html2canvas.hertzen.com/#
  • <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> 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com <img src="./images/img1.jpg"> <h2>条目2</h2> 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com <img src="./images/img1.jpg"> <h2>条目3</h2> 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com <img src="./images/img1.jpg"> <h2>条目4</h2> 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com <img src="./images/img1.jpg"> </body> </html>
    (2)导出结果如下:

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

    (1)如果网页内容比较多,只导出单页的 pdf 的话,那么多余的部分就会被自动截断无法显示。这就需要将内容自动拆分成多页导出。
    (2)而实现内容分页的方法比较取巧。我们不必针对每页内容专门生成一个 canvas ,而是统一都使用一个完整页面的 canvas 。即每一页 pdf 上显示的图片其实是相同的,只不过我们通过调整图片的位置,让每一页显示它需要显示的部分,从而产生了分页效果。
    <!DOCTYPE html>
        <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>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目2</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目3</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目4</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目5</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目6</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目7</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <img src="./images/img1.jpg">
        <h2>条目8</h2>
            欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com 欢迎访问hangge.com
        <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)导出结果如下: 上一篇JS - 使用jsPDF库生成PDF文件详解4(绘制图形、添加图片) 下一篇JS - 使用jsPDF-AutoTable库生成带表格的PDF文件1(安装配置、基本属性设置)
  • MySQL - 实现主从复制、主从同步功能教程2(多线程复制)
  • JS - Lodash工具库的使用详解2(使用throttle函数实现节流)
  • Intellij IDEA - 实现项目的热部署3(使用LiveReload实现静态资源热部署)
  • JS - 生成随机数的方法汇总(不同范围、类型的随机数)
  • IIS - 让不带www的域名重定向到带www的域名
  • Java - GoF设计模式详解21(状态模式)
  • java中的匿名内部类
  • Java - 《阿里Java开发手册》代码规范学习笔记1(编程规约)
  • TIOBE - 2022年2月编程语言排行
  • Atom - 解决Vue项目的'import' is only available in ES6警告
  •