如何在所有PDF页面上添加页眉和页脚在jsPDF中使用addHTML方法

时间:2018-04-16 09:39:50

标签: javascript html jspdf

我使用jspdf将html转换为pdf。我正在使用addHTML方法将html页面转换为pdf

  var htmlSource = $('#body')[0];

 function crate (){
   var pdf = new jsPDF('p','px');

  pdf.addHTML(
    htmlSource,10, 10, {pagesplit: true, margin: {top: 10, right: 10,bottom: 10, left: 10, useFor: 'page'}},
    function(dispose){
       pdf.save('datapdf.pdf');
    }
  );

}

我希望在所有页面上添加页眉和页脚,为页眉和页脚留空格。但是使用选项我只能在pdf的第一页上留下标题空间。

3 个答案:

答案 0 :(得分:5)

一种方法可能是在客户端浏览器中重新填充html页面呈现,以便完全按照您希望在pdf中打印它(然后只使用您刚刚创建的函数),因此以一种格式组成通过一系列垂直元素,如h,p1,f,h,p2,f,h,p3,f等(其中h = header,p1 ... pn是页面和f =页脚)而不是包含的系列只是h,p1,p2,p3,...,pn,f(现在)。

这意味着您可以访问html页面的源代码(因此它不仅仅是从互联网上获取的页面),因为如果它是外部资源,则可能是页眉和页脚是以编程方式构造的,以便还填充与页面的其他元素相关的空间(我认为这里是flex /应用垂直/或网格技术来渲染网页)。

另一个方面,如果要做这个方法,可能是内容中的分割并不总是可能的(我在这里没有想到破坏表或其他多页元素只有在使用滚动时才可见) ,但渲染可能会考虑页面的垂直显示(与桌面中的横向模式相反),以便从页面重绘元素。有时可能会使页脚和页眉更大,所以我不确定为什么你会想要通过这样做来花费最终打印页面的部分宝贵资产。 (解决方案可能是打开一个新窗口,从而以新格式重新呈现页面,甚至可能在现有页面后面,然后在关闭相应页面之前启动打印确认/或下载文件。)

另一种方法是更改​​函数以便使用页面的虚拟渲染(没有显示的页面) - 通过对函数进行更改而不是渲染本身。

然而,第二种方法也存在一些挑战。最初,在声明变量> var pdf'这是作为唯一的数据存储容器创建的,然后为其分配构造函数(var pdf = new jsPDF(' p',' px');)。但是,在下一步中,您将添加HTML内容(pdf.addHTML),该内容是单个元素,而不是多个实体。您应该更改该函数,以使其打印一个数组,您首先根据呈现的页面的尺寸计算元素。

也许代码会变成:

var fullpage, onepage, headd, foott, edges, contentt, he, fo, c, pages;
fullpage = document.body.scrollHeight; // height of all html page (not just the visible content)
onepage = 1200; // height of each single page printed in pdf - in pixels
headd = document.getElementById("header");
he =  headd.offsetHeight;
foott = document.getElementById("footer"); 
fo = foott.offsetHeight;
edges = he + fo;
contentt = onepage - edges; // height of content of each page printed

pages = [0];  // start to work with first page which obviously is there
fullpage -= onepage; // remove height of first printed page (containg both header and footer)
    pdf.addHTML( // create first page of pdf file
    htmlSource, 10, 10, {pagesplit: true, margin: {top: 10, right:
      10, bottom: 10, left: 10, useFor: 'page'}},
    function(dispose){
       pdf.save('datapdf.pdf');
    });   // this is your code

var i = 0; // start the counter

 while(fullpage > 0) { // start adding header + footer to remaining pages
  fullpage += edges; // if there is still a page 2...n we add edges, etc.
  i++;
  pages[i] = content(onepage) { // here you must insert the code for harvesting the n-st page content from your source code
    return htmlSource;
  }
     function addPages(i) {
         var eachpdf = "datapdf" + i + ".pdf";
          // <= here goes again your code, with a small change
          // pagesplit: false - instead of true, in order to speed the process, and also
          // pdf.save(eachpdf); - instead of pdf.save('datapdf.pdf');              
     }
 }

你试图实现的是创建一个系列he,p1,fo,he,p2,fo,he,p3,fo等(其中he = header,p1 ... pn是上面的页面/命名为datapdfi /和fo = footer)而不是仅包含h,p1,p2,p3,...,pn,f的系列。

这意味着您必须构建一个包含单独pdf页面的数组,如上面的代码所述。

我还没有为您创建用于分隔每个页面内容的代码(可能会返回htmlSource),但这严格依赖于您的页面呈现方式。

答案 1 :(得分:4)

建议的方法使用HTML的元素<header><footer>来实现此目的,例如:

<footer>
    <div style='text-align:center;'>Page <span class="pageCounter"></span>/<span class="totalPages"></span></div>
</footer>

请参阅https://github.com/MrRio/jsPDF/pull/260

答案 2 :(得分:1)

如果仍然有人在寻找简短的解决方案,您可以尝试一下,

对于页脚作为页数,


html2pdf().from(element).set(opt).toPdf().get('pdf').then(function (pdf) {
  var totalPages = pdf.internal.getNumberOfPages();

  for (i = 1; i <= totalPages; i++) {
    pdf.setPage(i);
    pdf.setFontSize(10);
    pdf.setTextColor(150);
    pdf.text('Page ' + i + ' of ' + totalPages, pdf.internal.pageSize.getWidth() - 100, pdf.internal.pageSize.getHeight() - 30);
  } 
}).save();

对于标题,您可以编写

pdfObject.text("my header text", 10, 10)

这将在每个页面位置x = 10,y = 10中将标题文本创建为my header text