繁体   English   中英

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

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

我正在使用 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');
    }
  );

}

我想在所有页面上添加 header 和页脚,或者为 header 和页脚留出空白。 但是使用选项我只能在 pdf 的第一页上留下 header 空间。

一种方法可能是在客户端浏览器中重新填充 html 页面渲染,以便完全按照您希望在 pdf 中打印的方式显示它(然后只需使用您刚刚在上面创建的函数),因此采用由一系列组成的格式垂直元素,如 h、p1、f、h、p2、f、h、p3、f 等(其中 h=header、p1 ... pn 是页面和 f=footer)而不是仅包含 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 是页面 / 上面 / 和 fo =footer) 而不是只包含 h, p1, p2, p3, ... , pn, f 的系列。

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

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

为此,建议使用 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

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",
    })

如果有人仍在寻找简短的解决方案,你可以试试这个,

对于页脚作为页数,


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

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