简体   繁体   English

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

[英]How Add Header and footer on all PDF page In jsPDF with addHTML method

I'm convert html to pdf using jspdf.我正在使用 jspdf 将 html 转换为 pdf。 I'm using addHTML method to convert html page in to 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');
    }
  );

} }

and I want add header and footer on all pages either leave blank space for header and footer.我想在所有页面上添加 header 和页脚,或者为 header 和页脚留出空白。 but using option I can only leave header space on first page of pdf.但是使用选项我只能在 pdf 的第一页上留下 header 空间。

One approach could be to refill the html page rendering in the client browser so as to display it exactly as you want it to be printed in the pdf (then simply use the function you just created above), therefore in a format composed by a series of vertical elements like h, p1, f, h, p2, f, h, p3, f, etc (where h=header, p1 ... pn are the pages and f=footer) instead of a series containing just h, p1, p2, p3, ... , pn, f (as is now).一种方法可能是在客户端浏览器中重新填充 html 页面渲染,以便完全按照您希望在 pdf 中打印的方式显示它(然后只需使用您刚刚在上面创建的函数),因此采用由一系列组成的格式垂直元素,如 h、p1、f、h、p2、f、h、p3、f 等(其中 h=header、p1 ... pn 是页面和 f=footer)而不是仅包含 h 的系列, p1, p2, p3, ... , pn, f (就像现在一样)。

This means that you might have access to the source code of the html page (so it's not just a page taken from the internet), because if it's an external resource maybe the dimensions of the header and footer are programatically constructed as to also fill spaces in relation with other elements of the page (and I think here of flex / applied vertically / or grid technologies in rendering the webpage).这意味着您可能可以访问 html 页面的源代码(因此它不仅仅是从互联网上获取的页面),因为如果它是外部资源,则页眉和页脚的尺寸可能会以编程方式构建以填充空格与页面的其他元素相关(我认为这里是在呈现网页时使用 flex / 垂直应用 / 或网格技术)。

Another aspect, if going to do this method, is that maybe the split in content is not always possible (and I'm not thinking here about destroying tables or other multi-page elements visible only when using the scrolling), but also the rendering might take into consideration the vertical display of the page (opposite to landscape mode as in desktop) in order to redraw the elements from the page.另一方面,如果要执行此方法,则内容的拆分可能并不总是可能的(而且我不是在这里考虑销毁仅在使用滚动时可见的表格或其他多页元素),而且渲染可能会考虑页面的垂直显示(与桌面中的横向模式相反),以便从页面重新绘制元素。 That sometimes could make the footer and header maybe larger, so I'm not sure why you would want to spend parts of valuable estate of the final printed page by doing that.这有时会使页脚和页眉可能更大,所以我不知道为什么你会想要通过这样做来花费最终打印页面的部分宝贵资产。 (The solution would be possibly to open a new window, thus re-rendering the page in the new format, maybe even behind the existing page, then launch the print confirmation / or download the file / before closing that respective page.) (解决方案可能是打开一个新窗口,从而以新格式重新呈现页面,甚至可能在现有页面后面,然后在关闭相应页面之前启动打印确认/或下载文件。)

The other way would be to change the function so to work with a virtual rendering of the page (no displayed page) - by making the changes into your function and not in the rendering itself.另一种方法是更改​​函数,以便使用页面的虚拟渲染(没有显示的页面) - 通过在您的函数中而不是在渲染本身中进行更改。

However, that second approach present also a few challenges, too.然而,第二种方法也存在一些挑战。 Initially, at declaring the variable 'var pdf' this is created as a unique data storage container, then you assign to it the constructor ( var pdf = new jsPDF('p','px'); ).最初,在声明变量 'var pdf' 时,它被创建为唯一的数据存储容器,然后您将构造函数分配给它( var pdf = new jsPDF('p','px'); )。 However on the next step you add to it a HTML content (pdf.addHTML) which is a single element, not a multiple entity.但是,在下一步中,您向其中添加了一个 HTML 内容 (pdf.addHTML),它是单个元素,而不是多个实体。 You should change the function in order to make it print an array where you first calculate the elements based on the dimensions of pages rendered.您应该更改函数以使其打印一个数组,您首先在其中根据呈现的页面的尺寸计算元素。

Maybe the code would become something as :也许代码会变成这样:

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');              
     }
 }

What you try to achieve is to create a series he, p1, fo, he, p2, fo, he, p3, fo, etc (where he=header, p1 ... pn are the pages / named datapdfi above / and fo=footer) instead of a series containing just h, p1, p2, p3, ... , pn, f.您尝试实现的是创建一个系列 he, p1, fo, he, p2, fo, he, p3, fo 等(其中 he=header, p1 ... pn 是页面 / 上面 / 和 fo =footer) 而不是只包含 h, p1, p2, p3, ... , pn, f 的系列。

This means you must construct an array containing separate pdf pages as explained in code above.这意味着您必须构造一个包含单独 pdf 页面的数组,如上面代码中所述。

I didn't yet create for you the code for separating the content of each page (which might return the htmlSource) however this is in strict dependence with the way in which your pages are rendered.我还没有为您创建用于分隔每个页面内容的代码(可能返回 htmlSource),但这与您的页面呈现方式有严格的关系。

There is a suggested method use HTML's elements <header> and <footer> for that purpose, for example:为此,建议使用 HTML 的元素<header><footer> ,例如:

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

See https://github.com/MrRio/jsPDF/pull/260https://github.com/MrRio/jsPDF/pull/260

let doc = new JsPDF('p', 'pt', 'a4')
    doc.html(componentRef.current, {
        callback: function (pdf) {
            //pdf.setFontSize(10)
            let totalPages = pdf.internal.pages.length-1
            for (let 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);
            }
            pdf.save(
                `delivery-${deliveryDate}.pdf`
            )
        },
        margin: [10, 0, 55, 0],
        autoPaging: "text",
    })

If someone still looking for the short solution, you can try this,如果有人仍在寻找简短的解决方案,你可以试试这个,

For the footer as number of page,对于页脚作为页数,


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();

For the header, you can write对于标题,你可以写

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

this will create the header text as my header text in each page position x=10, y=10.这将在每个页面位置 x=10, y=10 中创建标题文本作为my header text

pdf()
  {
    var margin= [9,9,9,9];
    var ptbdel=11;
    var rem=0;
    var invoiceNumber= this.orderDetail.invoiceNumber;
    var count =this.orderDetail.orderItems.length;
    debugger
    if(count>3)
    {
        margin=[10, 10, 10, 10]
        ptbdel=12;
    }
    var doc = new jsPDF('l','mm',"a4",);
    doc.html(document.getElementById('contentpopup')!, {
      autoPaging:"text",      
      callback: function (doc) {
      
        let i=doc.internal.pages.length-1
      rem=i-ptbdel;
      while(i>=(rem))
      {
        doc.deletePage(i)
        i--;
      }
        for(let i = 1 ; i<=doc.internal.pages.length;i++)
      {
        doc.setPage(i)
        doc.setFontSize(8)
        doc.text("Page "+doc.getCurrentPageInfo().pageNumber+" of "+(rem-1),270,5)
      }

      doc.save(invoiceNumber+'.pdf');
  },
      margin: margin,
      html2canvas: {
        
          scale: .25, //you have to adjust to your size
      },    
    });
}

Adjust Scale That Best Fits in Your Scenario.

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM