Comment faire la numérotation des pages dans l'en-tête / pied de page htmls avec wkhtmltopdf?

je suis en train de développer un système de facturation électronique, et l'une de nos fonctionnalités est de générer des PDF des factures, et de les envoyer par la poste. Nous avons plusieurs modèles pour les factures, et va créer plus tard, donc nous avons décidé d'utiliser des modèles HTML, générer un document HTML, puis le convertir en PDF. Mais nous sommes confrontés à un problème avec wkhtmltopdf, que pour autant que je sache (J'ai cherché sur Google depuis des jours pour trouver la solution) nous ne pouvons pas simplement à la fois utiliser HTML comme en-tête / pied de page, et afficher les numéros de page dans ils.

dans un rapport de bogue (ou tel) ( http://code.google.com/p/wkhtmltopdf/issues/detail?id=140) j'ai lu qu'avec JavaScript il est réalisable ce combo. Mais aucune autre information sur la façon de le faire peut être trouvé sur cette page, ou ailleurs.

il est, bien sûr, pas si important de forcer L'utilisation de JavaScript, si avec wkhtmltopdf une certaine magie CSS pouvait fonctionner, ce serait tout aussi génial, que toutes les autres solutions hackish.

Merci!

35
demandé sur Tamás Barta 2011-08-24 15:00:26

6 réponses

pour afficher le numéro de page et le nombre total de pages, vous pouvez utiliser ce code javascript dans votre pied de page ou en-tête:

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

Et l'appel getPdfInfo avec la page onload

bien sûr pdfkit_page_current et pdfkit_page_count seront les deux éléments qui montrent les chiffres.

Extrait de ici

20
répondu Dan Mazzini 2011-08-24 11:47:58

en fait c'est beaucoup plus simple qu'avec le code snippet. Vous pouvez ajouter l'argument sur la ligne de commande: --footer-center [page]/[topage].

comme richard l'a mentionné, d'autres variables se trouvent dans la section des pieds de page et des en-têtes de la documentation.

55
répondu makro 2016-10-04 18:41:11

Parmi quelques autres paramètres, le numéro de page et le nombre total de page sont passés au bas de page HTML comme paramètres de requête, comme indiqué dans les documents officiels:

... les arguments [numéro de page] sont envoyés aux documents html en-tête/pied de page à la mode GET.

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

donc la solution est de récupérer ces paramètres en utilisant un peu de JS et de les rendre dans le modèle HTML. Voici un exemple complet D'un pied de page 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() est appelé dans le corps onload. Nous obtenons ensuite chaque variable supportée à partir de la chaîne de requête et remplaçons le contenu de tous les éléments par un nom de classe correspondant.

28
répondu theDmi 2016-11-02 10:10:12

From the wkhtmltopdf documentation (http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) sous la rubrique "Footers and Headers" il y a un extrait de code pour obtenir la numérotation des pages:

<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>

il y a aussi plus de variables disponibles qui peuvent être substituées autres que les numéros de page pour utilisation dans les en-têtes/pieds de page.

14
répondu Richard Pursehouse 2017-08-01 14:03:16

La façon dont il DOIT être fait (qui est, si wkhtmltopdf pris en charge) serait en utilisant la bonne CSS Paginé Médias: http://www.w3.org/TR/css3-gcpm/

je cherche ce qu'il faut faire maintenant.

1
répondu rainabba 2014-01-23 23:55:45

approche sûre, même si vous utilisez XHTML (par exemple, avec thymeleaf). La seule différence avec l'autre solution est l'utilisation de // tags.

<!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>

Dernière remarque: si vous utilisez thymeleaf, remplacez <script><script th:inline="javascript">.

1
répondu Juangui Jordán 2018-01-26 11:28:02