首页 文章

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

提问于
浏览
36

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

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

强制使用JavaScript当然不是那么重要,如果使用wkhtmltopdf一些CSS魔法可以工作,它就像任何其他hackish解决方案一样令人敬畏 .

谢谢!

6 回答

  • 28

    要显示页码和总页数,您可以在页脚或 Headers 代码中使用此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;
      }
    

    并使用page onload调用getPdfInfo

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

    片段取自here

  • 58

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

    与richard一样,其他变量位于the documentation的页脚和页眉部分 .

  • 14

    在其他一些参数中, the page number and total page number are passed to the footer HTML as query params ,正如官方文档中所述:

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

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

    所以解决方案是使用一些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() 在正文 onload 中调用 . 然后,我们从查询字符串中获取每个受支持的变量,并使用匹配的类名替换所有元素中的内容 .

  • 1

    从 Headers "Footers and Headers"下的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>
    

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

  • 21

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

    我正在研究它现在需要做些什么 .

  • 1

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

    <!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: 如果使用百里香,请将 <script> 替换为 <script th:inline="javascript"> .

相关问题