2015-06-22 14 views
6

Oto nasza odpowiedź:Jak zdobyć numery stron w pdf generowane przez html z wkhtmltopdf

Obecnie używamy wkhtmltopdf do generowania PDF z danego szablonu html.

Niektóre informacje tła:

Używamy Sulu CMF budować naszą tylny koniec, który jest oparty na Symfony2. Paczka KnpSnappy jest używana jako opakowanie Symfony dla wkhtmltopdf.

Jak generować pliki PDF:

Jak wielu plików PDF podzielają ten sam nagłówek i stopkę stworzyliśmy BasePDFBundle która oferuje PDFManager zbudować PDF w locie przez dany szablon gałązka. Domyślnie dołączony jest ogólny nagłówek i stopka (zazwyczaj z nazwą i logo klienta).

stopce numery Problem/strony w stopce lub nagłówku():

Jest to bardzo przydatne, aby dodać numery stron do plików PDF, np. dla zamówień, jednak większość naszych treści jest dodawana dynamicznie (np. lista produktów). Ponieważ stylowanie pliku PDF może się zmieniać, a sama zawartość jest dynamicznie dodawana, musiał istnieć szybki i łatwy sposób dodania aktualnej i całkowitej strony do wygenerowanego pliku PDF. Oto, co zrobiliśmy:

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

Tak zmienne nazwy page i topage mogłyby być lepsze, jednak są one takie same jak owinięcie KnpSnappy używa podczas łączenia szablonów gałązka do ostatecznego szablonu PDF. Jest to najprostszy sposób na uzyskanie aktualnego i całkowitego numeru strony, ponieważ można pozwolić, aby opakowanie wykonało wszystkie obliczenia.

Po prostu trzeba zastąpić tekst znaczników html i to wszystko!

Różnice pomiędzy lokalnym komputerze i serwerze:

Jak wkhtmltopdf otwiera wirtualną przeglądarkę do „render” szablony gałązka może to prowadzić do błędów w swoim pokoleniu pdf na serwerze. Dowiedzieliśmy się, że używanie tagów zdarzeń, takich jak <body onload="doSomething()">, raczej nie powinno uruchamiać kodu javascript, tak jak zrobiliśmy to w powyższym przykładzie.

+1

Czy brakuje mi pytania? A może jest to odpowiedź na pytanie? –

+0

cóż, odpowiedź na to pytanie jest bezpośrednia =) – notsure

+0

Kluczowym punktem jest _nie_ użycie 'onload =" doSomething "'. Wszystkie przykłady, które widziałem, wykorzystywały to podejście i nie zadziałały. To robi. Dzięki! – codemonkey

Odpowiedz

0

Jeśli używasz KnpSnappy jako opakowania strony wkhtmltopdf, możesz skonfigurować różne opcje dla pliku pdf.

patrz „stopki i nagłówki:” sekcja w dokumentacji wkhtmltopdf, tutaj http://wkhtmltopdf.org/usage/wkhtmltopdf.txt

[strona] Zastąpiony przez liczbę stron aktualnie drukowanych

[topage] Zastąpiony przez liczbę ostatnia strona do zadrukowania

Poniżej próbki kontrolera Symfony2, sprawdź stopce-html opcję w $ pdfOptions tablicy, gdzie ha ve użył obu znaków zastępczych, aby wydrukować numer strony w stopce każdej strony pliku 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.'"', 
      ) 
     ); 

    } 
} 
Powiązane problemy