2015-06-22 10 views
6

Ecco la nostra risposta:Come ottenere i numeri di pagina in PDF generati da HTML con wkhtmltopdf

Attualmente stiamo utilizzando wkhtmltopdf per generare un PDF da un dato modello HTML.

Alcune informazioni di base:

Stiamo usando Sulu CMF per costruire il nostro back-end, che si basa su Symfony2. Il pacchetto KnpSnappy viene utilizzato come wrapper Symfony per wkhtmltopdf.

Come generare PDF:

Come molti file PDF condividono la stessa intestazione e piè di pagina che abbiamo creato un BasePDFBundle che offre una PDFManager per costruire il PDF al volo da un determinato modello di Twig. Per impostazione predefinita è inclusa un'intestazione e un piè di pagina generici (di solito con il nome e il logo del cliente).

il piè di pagina numeri Problema/pagina nel piè di pagina (o intestazione):

E 'molto utile per aggiungere i numeri di pagina a un file PDF ad es. per gli ordini, tuttavia, la maggior parte dei nostri contenuti viene aggiunta dinamicamente (ad esempio un elenco di prodotti). Poiché lo stile del PDF può cambiare e il contenuto stesso viene aggiunto dinamicamente, è necessario un modo semplice e rapido per aggiungere la pagina corrente e quella totale al PDF generato. Ecco cosa abbiamo fatto:

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"> 
<html> 
<head> 
    <base href="{{ app.request.schemeAndHttpHost }}" /> 
    <meta charset="utf-8"> 
    <meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1"> 
    <link rel="stylesheet" href="{{ asset('bundles/pdfbase/css/pdfstyles.css') }}"/> 
</head> 
<body class="footer"> 
    <div class="footer-container"> 
     <div class="footer-widget"> 
      <b>FooBar Company Name</b> 
     </div> 
     <div class="text-align-right"> 
      <span class="page"></span>/<span class="topage"></span> 
     </div> 
    </div> 

    <script type="text/javascript"> 
    (function() { 
     // get all url parameters and transform it to a list 
     // pdf generator adds a param for current and the total page sum 
     // add the value to the html elements 
     var urlParams = document.location.search.substring(1).split('&'); 
     var urlParamsList = {}; 
     var pagingElements = ['topage', 'page']; 

     for (var i in urlParams) { 
     var param = urlParams[i].split('=', 2); 
     urlParamsList[param[0]] = unescape(param[1]); 
     } 

     for (var i in pagingElements) { 
     var elem = document.getElementsByClassName(pagingElements[i]); 
     for (var j = 0; j < elem.length; ++j) { 
      elem[j].textContent = urlParamsList[pagingElements[i]]; 
     } 
     } 
    })(); 
    </script> 
</body> 

Sì i nomi delle variabili di page e topage potrebbe essere migliore, ma sono lo stesso del involucro KnpSnappy utilizza quando si unisce modelli ramoscello al modello PDF finale. Questo è il modo più semplice per ottenere il numero di pagina corrente e totale perché è possibile lasciare che il wrapper esegua tutti i calcoli.

Alla fine è sufficiente sostituire il testo dei tag html e questo è tutto!

Differenze tra il computer locale e il server:

Come wkhtmltopdf apre un browser virtuale per "rendere" i modelli ramoscello Questo potrebbe portare ad errori nella vostra generazione pdf sul vostro server. Abbiamo scoperto che non è una buona idea utilizzare i tag evento come <body onload="doSomething()"> piuttosto che attivare il codice javascript come abbiamo fatto nell'esempio sopra.

+1

Mi manca una domanda? O è questa una risposta alla ricerca di una domanda? –

+0

beh la domanda è direttamente risposta =) – notsure

+0

Il punto chiave è quello di _non_ usare 'onload =" doSomething "'. Tutti gli esempi che ho visto stavano usando quell'approccio e non ha funzionato. Questo fa. Grazie! – codemonkey

risposta

0

Se si utilizza KnpSnappy come wrapper di wkhtmltopdf, è possibile impostare varie opzioni per il pdf.

vedere "piè di pagina e intestazioni:" inserito nella documentazione wkhtmltopdf, qui http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

[page] Sostituito dal numero delle pagine in fase di stampa

[topage] Sostituito per il numero di l'ultima pagina da stampare

seguito è campione di controllo Symfony2, controllare footer-html opzione nella gamma $ pdfOptions, dove ho ettaro Ho usato entrambi i segnaposto per stampare il numero di pagina nel piè di pagina di ogni pagina del file pdf.

<?php 

namespace Rm\PdfBundle\Controller; 

use Symfony\Component\HttpFoundation\Request; 
use Symfony\Component\HttpFoundation\Response; 
use Symfony\Bundle\FrameworkBundle\Controller\Controller; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Route; 
use Sensio\Bundle\FrameworkExtraBundle\Configuration\Method; 

/** 
* Pdf controller 
*/ 
class PdfController extends Controller 
{ 
    /** 
    * Serve pdf 
    * 
    * @Route("/article/{slug}", name="rm_pdf_view") 
    * @Method({"GET"}) 
    */ 
    public function viewAction(Request $request, $slug) 
    { 

     // build html 
     $html = $this->renderView('RmPdfBundle:Pdf:view.html.twig', array(
      'data' => $yourDataToTemplate, 
     )); 


     // prepare pdf options 
     $pdfOptions = array(

      'footer-html'  => '<p>Page : [page] of [pageTo]</p>', 

      'footer-font-size' => '10', 
      'page-size'  => 'A4', 
      'orientation'  => 'Portrait', 
      'margin-top'  => 10, 
      'margin-bottom' => 20, 
      'margin-left'  => 15, 
      'margin-right'  => 15, 
      ); 

     // file name of pdf 
     $pdfFileName = "nameOfYourPdfFile.pdf"; 

     // server pdf file to user using knp_snappy.pdf service 
     return new Response(
      $this->get('knp_snappy.pdf')->getOutputFromHtml($html, $pdfOptions), 
      200, 
      array(
       'Content-Type'   => 'application/pdf', 
       'Content-Disposition' => 'attachment; filename="'.$pdfFileName.'"', 
      ) 
     ); 

    } 
}