Javascript 如何使用 wkhtmltopdf 在页眉/页脚 html 中进行页码编号?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/7174359/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-08-24 01:11:29  来源:igfitidea点击:

How to do page numbering in header/footer htmls with wkhtmltopdf?

javascriptcsswkhtmltopdfcss-paged-media

提问by Tamás Barta

I'm developing an electronic invoicing system, and one of our features is generating PDFs of the invoices, and mailing them. We have multiple templates for invoices, and will create more later, so we decided to use HTML templates, generate HTML document, and then convert it to PDF. But we're facing a problem with wkhtmltopdf, that as far as I know (I've been Googleing for days to find the solution) we cannot simply both use HTML as header/footer, and show page numbers in them.

我正在开发一个电子发票系统,我们的功能之一是生成发票的 PDF 文件并邮寄。我们有多个发票模板,稍后会创建更多,因此我们决定使用HTML模板,生成HTML文档,然后将其转换为PDF。但是我们正面临 wkhtmltopdf 的一个问题,据我所知(我已经在谷歌上搜索了几天以找到解决方案)我们不能简单地使用 HTML 作为页眉/页脚,并在其中显示页码。

In a bug report (or such) ( http://code.google.com/p/wkhtmltopdf/issues/detail?id=140) I read that with JavaScript it is achievable this combo. But no other information on how to do it can be found on this page, or elsewhere.

在错误报告(或此类)(http://code.google.com/p/wkhtmltopdf/issues/detail?id=140)中,我读到使用 JavaScript 可以实现此组合。但是在此页面或其他地方找不到有关如何执行此操作的其他信息。

It is, of course not so important to force using JavaScript, if with wkhtmltopdf some CSS magic could work, it would be just as awesome, as any other hackish solutions.

当然,强制使用 JavaScript 并不是那么重要,如果使用 wkhtmltopdf 一些 CSS 魔法可以工作,它会和任何其他黑客解决方案一样棒。

Thanks!

谢谢!

采纳答案by Dan Mazzini

To show the page number and total pages you can use this javascript snippet in your footer or header code:

要显示页码和总页数,您可以在页脚或页眉代码中使用此 javascript 代码段:

  var pdfInfo = {};
  var x = document.location.search.substring(1).split('&');
  for (var i in x) { var z = x[i].split('=',2); pdfInfo[z[0]] = unescape(z[1]); }
  function getPdfInfo() {
    var page = pdfInfo.page || 1;
    var pageCount = pdfInfo.topage || 1;
    document.getElementById('pdfkit_page_current').textContent = page;
    document.getElementById('pdfkit_page_count').textContent = pageCount;
  }

And call getPdfInfo with page onload

并在页面加载时调用 getPdfInfo

Of course pdfkit_page_current and pdfkit_page_count will be the two elements that show the numbers.

当然 pdfkit_page_current 和 pdfkit_page_count 将是显示数字的两个元素。

Snippet taken from here

摘自这里的片段

回答by makro

Actually it's much simpler than with the code snippet. You can add the following argument on the command line: --footer-center [page]/[topage].

实际上它比代码片段简单得多。您可以在命令行上添加以下参数:--footer-center [page]/[topage].

Like richard mentioned, further variables are in the Footers and Headers section of the documentation.

就像理查德提到的,更多的变量在文档的页脚和页眉部分。

回答by theDmi

Among a few other parameters, the page number and total page number are passed to the footer HTML as query params, as outlined in the official docs:

在其他一些参数中,页码和总页码作为查询参数传递给页脚 HTML,如官方文档中所述:

... the [page number] arguments are sent to the header/footer html documents in GET fashion.

... [页码] 参数以 GET 方式发送到页眉/页脚 html 文档。

Source: http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

来源:http: //wkhtmltopdf.org/usage/wkhtmltopdf.txt

So the solution is to retrieve these parameters using a bit of JS and rendering them into the HTML template. Here is a complete working example of a footer HTML:

所以解决方案是使用一些 JS 检索这些参数并将它们呈现到 HTML 模板中。这是页脚 HTML 的完整工作示例:

<!doctype html>
<html>
<head>
    <meta charset="utf-8">
    <script>
        function substitutePdfVariables() {

            function getParameterByName(name) {
                var match = RegExp('[?&]' + name + '=([^&]*)').exec(window.location.search);
                return match && decodeURIComponent(match[1].replace(/\+/g, ' '));
            }

            function substitute(name) {
                var value = getParameterByName(name);
                var elements = document.getElementsByClassName(name);

                for (var i = 0; elements && i < elements.length; i++) {
                    elements[i].textContent = value;
                }
            }

            ['frompage', 'topage', 'page', 'webpage', 'section', 'subsection', 'subsubsection']
                .forEach(function(param) {
                    substitute(param);
                });
        }
    </script>
</head>
<body onload="substitutePdfVariables()">
    <p>Page <span class="page"></span> of <span class="topage"></span></p>
</body>
</html>

substitutePdfVariables()is called in body onload. We then get each supported variable from the query string and replace the content in all elements with a matching class name.

substitutePdfVariables()在体内被称为onload。然后我们从查询字符串中获取每个支持的变量,并用匹配的类名替换所有元素中的内容。

回答by Richard Pursehouse

From the wkhtmltopdf documentation (http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) under the heading "Footers and Headers" there is a code snippet to achieve page numbering:

从 wkhtmltopdf 文档 ( http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) 标题“页脚和页眉”下有一个代码片段来实现页码:

<html><head><script>
function subst() {
  var vars={};
  var x=document.location.search.substring(1).split('&');
  for(var i in x) {var z=x[i].split('=',2);vars[z[0]] = unescape(z[1]);}
  var x=['frompage','topage','page','webpage','section','subsection','subsubsection'];
  for(var i in x) {
    var y = document.getElementsByClassName(x[i]);
    for(var j=0; j<y.length; ++j) y[j].textContent = vars[x[i]];
  }
}
</script></head><body style="border:0; margin: 0;" onload="subst()">
<table style="border-bottom: 1px solid black; width: 100%">
  <tr>
    <td class="section"></td>
    <td style="text-align:right">
      Page <span class="page"></span> of <span class="topage"></span>
    </td>
  </tr>
</table>
</body></html>

There are also more available variables which can be substituted other than page numbers for use in Headers/Footers.

除了页码之外,还有更多可用的变量可以替换用于页眉/页脚。

回答by Juangui Jordán

Safe approach, even if you are using XHTML (for example, with thymeleaf). The only difference with other's solution is the use of // tags.

安全的方法,即使您使用的是 XHTML(例如,使用 thymeleaf)。与其他解决方案的唯一区别是使用了 // 标签。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <script>
        /*<![CDATA[*/
        function subst() {
            var vars = {};
            var query_strings_from_url = document.location.search.substring(1).split('&');
            for (var query_string in query_strings_from_url) {
                if (query_strings_from_url.hasOwnProperty(query_string)) {
                    var temp_var = query_strings_from_url[query_string].split('=', 2);
                    vars[temp_var[0]] = decodeURI(temp_var[1]);
                }
            }
            var css_selector_classes = ['page', 'topage'];
            for (var css_class in css_selector_classes) {
                if (css_selector_classes.hasOwnProperty(css_class)) {
                    var element = document.getElementsByClassName(css_selector_classes[css_class]);
                    for (var j = 0; j < element.length; ++j) {
                        element[j].textContent = vars[css_selector_classes[css_class]];
                    }
                }
            }
        }
        /*]]>*/
    </script>
</head>
<body onload="subst()">
    <div class="page-counter">Page <span class="page"></span> of <span class="topage"></span></div>
</body>

Last note:if using thymeleaf, replace <script>with <script th:inline="javascript">.

最后注意:如果使用百里香叶,请替换<script><script th:inline="javascript">.

回答by Adolfo Martinez

My example shows how to hide some text on a particular page, for this case it shows the text from page 2 onwards

我的示例显示了如何在特定页面上隐藏一些文本,在这种情况下,它显示了从第 2 页开始的文本

<span id='pageNumber'>{#pageNum}</span>
<span id='pageNumber2' style="float:right; font-size: 10pt; font-family: 'Myriad ProM', MyriadPro;"><strong>${siniestro.numeroReclamo}</strong></span>
<script>
    var elem = document.getElementById('pageNumber');
    document.getElementById("pageNumber").style.display = "none";
       if (parseInt(elem.innerHTML) <= 1) {
           elem.style.display = 'none';
           document.getElementById("pageNumber2").style.display = "none";
       }
</script>

回答by rainabba

The way it SHOULD be done (that is, if wkhtmltopdf supported it) would be using proper CSS Paged Media: http://www.w3.org/TR/css3-gcpm/

它应该完成的方式(即,如果 wkhtmltopdf 支持它)将使用适当的 CSS 分页媒体:http: //www.w3.org/TR/css3-gcpm/

I'm looking into what it will take now.

我正在研究现在需要什么。