2011-08-24 21 views
31

Sto sviluppando un sistema di fatturazione elettronica e una delle nostre caratteristiche è la generazione di PDF delle fatture e la loro spedizione. Disponiamo di più modelli per le fatture e ne creeremo altri in seguito, quindi abbiamo deciso di utilizzare modelli HTML, generare documenti HTML e convertirli in PDF. Ma stiamo affrontando un problema con wkhtmltopdf, che per quanto ne so (sono stato Googleing per giorni a trovare la soluzione) non possiamo semplicemente usare entrambi HTML come intestazione/piè di pagina e mostrare i numeri di pagina al loro interno.Come fare la numerazione delle pagine in html header/footer con wkhtmltopdf?

In un bug report (o simile) (http://code.google.com/p/wkhtmltopdf/issues/detail?id=140) Ho letto che con JavaScript è possibile ottenere questo combo. Ma nessuna altra informazione su come farlo può essere trovata in questa pagina o altrove.

Ovviamente non è così importante forzare l'uso di JavaScript, se con wkhtmltopdf alcuni CSS potrebbero funzionare, sarebbe altrettanto fantastico, come qualsiasi altra soluzione di hacker.

Grazie!

risposta

19

Per visualizzare il numero di pagina e le pagine totali è possibile utilizzare questo frammento di JavaScript nel piè di pagina o intestazione codice:

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

E chiamare getPdfInfo con la pagina onload

Naturalmente pdfkit_page_current e pdfkit_page_count sarà il due elementi che mostrano i numeri.

frammento tratto da here

+4

wkhtmltopdf non è PDFKit. – thirtydot

+15

PDFKit è solo un wrapper Ruby per wkhtmltopdf – danmaz74

+0

Oops. Ci scusiamo per non aver verificato il tuo link. – thirtydot

10

Dalla documentazione wkhtmltopdf (http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html) sotto i "piè di pagina e intestazioni" intestazione c'è un frammento di codice per ottenere la numerazione delle pagine:

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

ci sono anche più variabili disponibili che può essere sostituito da numeri di pagina diversi da utilizzare in Intestazioni/Piè di pagina.

+0

Bello vedere la documentazione aggiornata :) –

+0

BROKEN LINK: http://madalgo.au.dk/~jakobt/wkhtmltoxdoc/wkhtmltopdf-0.9.9-doc.html – marienke

+1

Di per sé, questo frammento non fa nulla. La pagina a cui hai collegato include il codice Javascript che in realtà popola lo 'span's nello snippet. – joshuahhh

50

In realtà è molto più semplice rispetto allo snippet di codice. È possibile aggiungere il seguente argomento sulla riga di comando: --footer-center [page]/[topage].

Come richard menzionato, ulteriori variabili si trovano nella sezione Piè di pagina e intestazioni di the documentation.

+14

Esatto, ma in questo modo non puoi usare l'HTML, come ricordo di aver lavorato su questo progetto. –

+0

Non funziona per me ... :( –

+0

Ottima soluzione per semplici intestazioni/piè di pagina –

1

Il modo in cui dovrebbe essere fatto (cioè, se wkhtmltopdf ha sostenuto) sarebbe utilizzando una corretta CSS paging media: http://www.w3.org/TR/css3-gcpm/

sto cercando in che cosa ci vorrà ora.

+1

Ho anche guardato i media pagati CSS, ma le intestazioni e i piè di pagina sono resi individualmente per pagina, quindi non possono avere una di queste informazioni. Il dilemma era: come risolvere il problema di dover creare e posizionare intestazioni e piè di pagina su ogni pagina con i CSS. Non sono riuscito a trovare una risposta, quindi il meccanismo di intestazione e footer di wkhtmltopdf sembrava un modo più semplice. –

+1

Questa non è una risposta, se wkhtmltopdf non lo supporta? – aknuds1

23

Tra un paio di altri parametri, il numero di pagina e il numero totale di pagine vengono passati al HTML piè di pagina di query params, come indicato nella documentazione ufficiale:

... il [numero di pagina] gli argomenti vengono inviati ai documenti intestazione/piè di pagina html in GET fashion.

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

Quindi la soluzione è quella di recuperare questi parametri utilizzando un po 'di JS e rendendoli nel modello HTML.Ecco un esempio completo di lavoro di un piè di pagina 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() è chiamato nel corpo onload. Otteniamo quindi ogni variabile supportata dalla stringa di query e sostituiamo il contenuto di tutti gli elementi con un nome di classe corrispondente.

+0

Mostra valore null ... perché? – Dhara

+0

funziona fantastico, grazie! – fay

+0

Quale framework stai usando? In .NET non so come usarlo dal codice generato in C#. (ha bisogno del browser per attivare) – FrenkyB

0

Approccio sicuro, anche se si utilizza XHTML (ad esempio, con thymeleaf). L'unica differenza con la soluzione di altri è l'uso di // tag.

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

Ultima nota: se si utilizza thymeleaf, sostituire <script> con <script th:inline="javascript">.

Problemi correlati