带有 addPage 的 jsPDF html 方法在生成的 PDF 中拆分页面

jsPDF html method with addPage to split pages in generated PDF

我正在使用 jsPDF 的 html 方法为一些 html 生成 PDF,其中包含多个段落 p 每个 p 包含 50-500 之间的单词。使用我定义的样式正确生成 PDF。我面临的唯一问题是当 p 标签的内容溢出到 PDF 中的新页面时,切断了部分文本,如下所示:

为了解决这个问题,我需要在我的代码中引入 addPage,以便在我希望的地方插入一个 "page break"。这是与 jsPDF 的 text 函数一起使用的 addPage 示例:

var doc = new jsPDF('p', 'pt', 'letter');
doc.text(20, 20, 'first text');
doc.addPage();
doc.text(20, 20, 'second text');
doc.addPage();
doc.text(20, 20, 'third text');
doc.save();

我想为 html 做同样的事情,这是我使用的代码:

var doc = new jsPDF('p', 'pt', 'letter');
doc.html($("#p1")[0], {
    callback: function (doc) {
        doc.addPage('letter', 'p');

        doc.html($("#p2")[0], {
            callback: function (doc) {
                doc.save();
            }
        });
    }
});

以上生成了一个PDF,内容为2页。但是假设在第二页上的内容在第一页上,在第一页的内容之上。换句话说,#p2 内容粘贴在 #p1 内容之上。

这是代码片段,但请注意,当您尝试 运行 代码时,SO 会抛出 跨域错误 ,因此您需要 运行 下面的外部 SO:

function wrap() {
  var doc = new jsPDF('p', 'pt', 'letter');
  doc.html($("#p1")[0], {
    callback: function(doc) {
      doc.addPage('letter', 'p');
      doc.html($("#p2")[0], {
        callback: function(doc) {
          doc.save();
        }
      });
    }
  });
}
<script src="https://cdnjs.cloudflare.com/ajax/libs/jquery/3.3.1/jquery.min.js"></script>
<script src="https://unpkg.com/jspdf@latest/dist/jspdf.min.js"></script>
<script src="https://cdn.jsdelivr.net/npm/html2canvas@1.0.0-alpha.12/dist/html2canvas.js"></script>

<button id="btn" onclick="wrap()">Test</button>
<div id="lipsum">
  <p id="p1">
    Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas sed risus at orci elementum consequat. Suspendisse laoreet rhoncus dignissim. Aliquam a ultrices orci, in elementum nibh. Aliquam mollis erat at vehicula pellentesque. Nunc suscipit, leo
    at convallis lobortis, odio ipsum euismod sapien, auctor accumsan velit eros non risus. Cras sagittis nisi non orci finibus porta. Sed finibus ac eros eu tincidunt. Nam viverra egestas augue vestibulum elementum. Suspendisse convallis felis sodales,
    ornare neque ut, elementum dui. Mauris ac orci mattis, tristique nisi quis, ultricies urna. In tincidunt, dolor vitae euismod mattis, lorem arcu placerat velit, quis auctor est est et sem. Aenean convallis finibus posuere. Sed feugiat orci a lacinia
    efficitur. Ut semper, purus quis convallis vehicula, mi risus rhoncus arcu, et feugiat neque turpis non tellus.
  </p>
  <p id="p2">
    Mauris dapibus felis leo, vitae vestibulum purus feugiat sit amet. Fusce ac dapibus nunc. Etiam congue mi neque. Maecenas eget blandit turpis. Suspendisse volutpat, urna eu facilisis congue, elit felis faucibus velit, venenatis semper sem sem ut ante.
    Class aptent taciti sociosqu ad litora torquent per conubia nostra, per inceptos himenaeos. Praesent blandit congue sapien. Curabitur non fermentum felis, sit amet auctor nunc. Cras id tellus nunc.
  </p>
  <p id="p3">
    In lacinia lectus nec quam dapibus eleifend. Phasellus iaculis eget massa non aliquam. Cras interdum gravida hendrerit. Suspendisse rhoncus pretium erat non malesuada. Fusce sit amet finibus est. Phasellus quis dapibus orci. Nunc iaculis felis odio, et
    dictum leo mollis sed. Morbi ultrices turpis at mi pellentesque, sit amet consectetur tortor volutpat. Mauris ac nunc ac nunc pellentesque lacinia. Duis at ligula tristique, maximus sapien sit amet, pulvinar neque.
  </p>

</div>

另请注意,html2canvas js 使用的版本在这里很重要。有关详细信息,请参阅

使用 this,特别是模板(第 125-150 行),我找到了一个解决方案 "moves" 第二个(后续)页面到正确的 y (y: 792) 坐标:

function wrap() {
  var doc = new jsPDF('p', 'pt', 'letter');
  doc.html($("#p1")[0], {
    callback: function(doc) {
      doc.addPage('letter', 'p');
      doc.html($("#p2")[0], {
        callback: function(doc) {
          doc.save();
        }, y:792
      });
    }, html2canvas: {scale: 1}
  });
}

其中792是单个字母页面的纵向长度。换句话说,p2 在具有定义的 y 轴坐标的位置上呈现。

可以更新上面的代码(递归函数)以针对多个 p 元素执行此操作,甚至可以根据其他条件拆分页面。我希望这对某人有所帮助。

注意:html2canvas: {scale: 1} 用于解决我在移动设备上生成的 PDF 页面缩放时遇到的另一个问题。