HTML2pdf 设置以及页眉和页脚的选项:

huangapple go评论109阅读模式
英文:

HTML2pdf settings and options for header and footer

问题

我在我的应用程序中使用了Vue JS。我有一个要打印的表格内容,并且我使用了HTML2pdf。我可以在其中添加页眉、页脚、分页等内容。问题是 - 表格内容是动态的,表格的长度以及列数取决于用户的筛选条件。它会自动换行,因此我无法在我的HTML中手动拆分表格。目标是在每个页面上添加表头。我可以使用DOM动态获取表头(列数和名称取决于用户选择),并将其添加到页眉中。但它显示得就像一个字符串一样。页眉中的每个列名与列内容不匹配。我的表格列具有固定的相等大小,所以我想,如果我可以将这个页眉字符串拉伸到最大宽度,它在视觉上就会匹配。

问题:如何将页眉字符串拉伸到pdf页面的全宽?可以进行样式设置并添加边框会很好。或者是否有更有效的方法来在每个页面上获取表格表头?
附:表格样式本身是使用网格列自定义样式的,不是使用th/td类,如果这有关系。

这是我的代码:

const tableHeader = computed(() => {
 let headerCollection = document.getElementById('header-pdf')
  ?.children as HTMLCollection
 let arr = []
 for (let i = 0; i < headerCollection.length; i++) {
 arr.push(headerCollection[i].innerHTML)
}
var headerString = arr.toString().replace(/\,/g, ' | ').toUpperCase()

return headerString
})

export const exportToPDF = (elementId: string, orientation: string) => {
var element = document.getElementById(elementId)
var opt = {
filename: fileName.value,
margin: [15, 2, 15, 6],
pagebreak: { mode: 'css' },
jsPDF: { format: 'a4', orientation: orientation, putTotalPages: true }
}
html2pdf().set(opt).from(element).toPdf().get('pdf')

.then((pdf: any) => {
var totalPages = pdf.internal.getNumberOfPages();
var pageHeight = pdf.internal.pageSize.height || pdf.internal.pageSize.getHeight();
var pageWidth = pdf.internal.pageSize.width || pdf.internal.pageSize.getWidth();
var footerText = '';
var i;
for (i = 1; i <= totalPages; i++) {
    if (i > 1) {
        pdf.setPage(i);
        pdf.setFontSize(8);
        pdf.setTextColor(150);

       pdf.text('page ' + i + ' of ' + totalPages + '\n' + footerText , pageWidth / 2, 
        pageHeight - 5, {align: 'center'});
       pdf.setFontSize(12);
       pdf.text(tableHeader .value , pageWidth / 2, 10, {align: 'center'});

    }
  }}).save()
}

HTML2pdf 设置以及页眉和页脚的选项:

英文:

I use Vue JS in my app. I have a table content to print aand i use HTML2pdf. I can add there header and footer, pagination etc. The question is - table content is dynamic and the length of the table, as well as number of columns depends on the users filters. It breaks auto, so I cannot split the table manually in my html. The goal is to add table header to each of the page. I can get table headers using DOM dynamically (number cols and names depends on user choise) and add it to my header. But it displays just like a string. Every col name from header does not match col content. My table cols have fixed equal size, so I suppose, if I can stretch this header string to max width, visually it will match.

Question: How to stretch the header string to the full width of pdf page? Could be nice to style and add borders. Or there is more efficient way do get table header on each page?
ps. Table style itself is custom styled with grid cols, not table class with th/td if it matters.

Here is my code:

const tableHeader = computed(() =&gt; {
let headerCollection = document.getElementById(&#39;header-pdf&#39;)
?.children as HTMLCollection
let arr = []
for (let i = 0; i &lt; headerCollection.length; i++) {
arr.push(headerCollection[i].innerHTML)
}
var headerString = arr.toString().replace(/\,/g, &#39; | &#39;).toUpperCase()
return headerString
})
export const exportToPDF = (elementId: string, orientation: string) =&gt; {
var element = document.getElementById(elementId)
var opt = {
filename: fileName.value,
margin: [15, 2, 15, 6],
pagebreak: { mode: &#39;css&#39; },
jsPDF: { format: &#39;a4&#39;, orientation: orientation, putTotalPages: true }
}
html2pdf().set(opt).from(element).toPdf().get(&#39;pdf&#39;)
.then((pdf: any) =&gt; {
var totalPages = pdf.internal.getNumberOfPages();
var pageHeight = pdf.internal.pageSize.height || pdf.internal.pageSize.getHeight();
var pageWidth = pdf.internal.pageSize.width || pdf.internal.pageSize.getWidth();
var footerText = &#39;&#39;;
var i;
for (i = 1; i &lt;= totalPages; i++) {
if (i &gt; 1) {
pdf.setPage(i);
pdf.setFontSize(8);
pdf.setTextColor(150);
pdf.text(&#39;page &#39; + i + &#39; of &#39; + totalPages + &#39;\n&#39; + footerText , pageWidth / 2, 
pageHeight - 5, {align: &#39;center&#39;});
pdf.setFontSize(12);
pdf.text(tableHeader .value , pageWidth / 2, 10, {align: &#39;center&#39;});
}
}}).save()

HTML2pdf 设置以及页眉和页脚的选项:

答案1

得分: 1

主要问题是您的标题字符串被整体居中,而不是每个列标题都与其关联的列一起居中,因为它被视为单个实体。

解决此问题的一种方法是根据列数和宽度确定每个标题应放置的位置。然后可以使用这些位置将每个标题立即放在其相应的列上。

这是您的代码的修订版本,其中标题已正确分为其组成部分:

const tableHeader = computed(() => {
  let headerCollection = document.getElementById('header-pdf')?.children as HTMLCollection;
  let arr = [];
  for (let i = 0; i < headerCollection.length; i++) {
    arr.push(headerCollection[i].innerHTML);
  }
  return arr.map(e => e.toUpperCase());
})

export const exportToPDF = (elementId: string, orientation: string) => {
  var element = document.getElementById(elementId);
  var opt = {
    filename: fileName.value,
    margin: [15, 2, 15, 6],
    pagebreak: { mode: 'css' },
    jsPDF: { format: 'a4', orientation: orientation, putTotalPages: true }
  }
  
  html2pdf().set(opt).from(element).toPdf().get('pdf').then((pdf: any) => {
    var totalPages = pdf.internal.getNumberOfPages();
    var pageHeight = pdf.internal.pageSize.height || pdf.internal.pageSize.getHeight();
    var pageWidth = pdf.internal.pageSize.width || pdf.internal.pageSize.getWidth();
    var footerText = '';
    var i;

    var colWidth = pageWidth / tableHeader.value.length; // Divide total width by number of headers
    var headers = tableHeader.value;

    for (i = 1; i <= totalPages; i++) {
      if (i > 1) {
        pdf.setPage(i);
        pdf.setFontSize(8);
        pdf.setTextColor(150);
        pdf.text('page ' + i + ' of ' + totalPages + '\n' + footerText , pageWidth / 2, pageHeight - 5, {align: 'center'});
        pdf.setFontSize(12);

        headers.forEach((text, index) => {
          var position = (colWidth / 2) + (colWidth * index);
          pdf.text(text, position, 10, {align: 'center'});
        })
      }
    }
  }).save();
}

这里的主要区别是,我们将标题保留为数组,并使用forEach函数分别定位每个标题,而不是将它们转换为字符串。该代码假设每列的宽度均匀分配给其标题。然后,标题定位在其相应列的中间。

应用样式和边框稍微复杂一些,因为html2pdf使用jsPDF包,通常用于文本放置而不是复杂的设计。您可能可以使用line函数构建线来充当边框,但可能无法添加诸如背景颜色或其他复杂样式等内容。

请在您的环境中测试此代码,确保它能正常工作。

英文:

The main problem is that your header string is being centered as a whole rather than with each column header being centered over its associated column because it is being treated as a single entity.

One solution to this problem is to figure out where each header should be placed based on the number of columns and their widths. These positions can then be used to put each heading immediately over its corresponding column.

Here is a revised version of your code where the header is correctly divided into its component parts:

const tableHeader = computed(() =&gt; {
let headerCollection = document.getElementById(&#39;header-pdf&#39;)?.children as HTMLCollection;
let arr = [];
for (let i = 0; i &lt; headerCollection.length; i++) {
arr.push(headerCollection[i].innerHTML);
}
return arr.map(e =&gt; e.toUpperCase());
})
export const exportToPDF = (elementId: string, orientation: string) =&gt; {
var element = document.getElementById(elementId);
var opt = {
filename: fileName.value,
margin: [15, 2, 15, 6],
pagebreak: { mode: &#39;css&#39; },
jsPDF: { format: &#39;a4&#39;, orientation: orientation, putTotalPages: true }
}
html2pdf().set(opt).from(element).toPdf().get(&#39;pdf&#39;).then((pdf: any) =&gt; {
var totalPages = pdf.internal.getNumberOfPages();
var pageHeight = pdf.internal.pageSize.height || pdf.internal.pageSize.getHeight();
var pageWidth = pdf.internal.pageSize.width || pdf.internal.pageSize.getWidth();
var footerText = &#39;&#39;;
var i;
var colWidth = pageWidth / tableHeader.value.length; // Divide total width by number of headers
var headers = tableHeader.value;
for (i = 1; i &lt;= totalPages; i++) {
if (i &gt; 1) {
pdf.setPage(i);
pdf.setFontSize(8);
pdf.setTextColor(150);
pdf.text(&#39;page &#39; + i + &#39; of &#39; + totalPages + &#39;\n&#39; + footerText , pageWidth / 2, pageHeight - 5, {align: &#39;center&#39;});
pdf.setFontSize(12);
headers.forEach((text, index) =&gt; {
var position = (colWidth / 2) + (colWidth * index);
pdf.text(text, position, 10, {align: &#39;center&#39;});
})
}
}
}).save();
}

Here, the main difference is that we preserve the headers as an array and position each one separately using the forEach function rather than converting them into a string. This code takes for granted that each column will have a width that is distributed evenly among its headers. After that, the headings are positioned in the middle of their corresponding columns.

It's a little more challenging to apply styles and borders because html2pdf uses the jsPDF package, which is typically used for text placement rather than sophisticated design. Using the line function, you might possibly construct lines to serve as borders, but it might not be feasible to add things like background color or other elaborate styles.

Please test this code in your environment to make sure it works.

huangapple
  • 本文由 发表于 2023年6月26日 17:13:47
  • 转载请务必保留本文链接:https://go.coder-hub.com/76555250.html
匿名

发表评论

匿名网友

:?: :razz: :sad: :evil: :!: :smile: :oops: :grin: :eek: :shock: :???: :cool: :lol: :mad: :twisted: :roll: :wink: :idea: :arrow: :neutral: :cry: :mrgreen:

确定