[Symfony] Jak wygenerować plik PDF ?

Programowanie
[Symfony] Jak wygenerować plik PDF ?

Dzięki bogatej bibliotece pakietów stworzonych przez programistów dla Symfony nie musimy wszystkiego pisać od zera. W tym przypadku posłużymy się pakietem KnpSnappyBundle, który wymaga PHP 5.3+ oraz wykorzystuje do swojego działania wkhtmltopdf. Pakiet ten pozwala na wygenerowanie pliku pdf lub obrazka na podstawie dostarczonego kodu html, do wyrenderowania html-a jest użyty silnik Webkit.

Instalacja

Do pliku composer.json dodajemy wpis:

{
    "require": {
        "knplabs/knp-snappy-bundle": "dev-master"
    }
}

Następnie przeprowadzamy aktualizację:

php composer.phar update

I włączamy pobrany pakiet do naszej aplikacji wpisem w app/AppKernel.php

public function registerBundles()
{
    $bundles = array(
        //...
        new Knp\Bundle\SnappyBundle\KnpSnappyBundle(),
        //...

Do działania pakietu konieczna jest aplikacja w systemie.

Linux

sudo apt-get install xvfb wkhtmltopdf

Windows

Pobieramy oprogramowanie ze strony producenta: http://wkhtmltopdf.org/downloads.html

Konfiguracja

Dokonujemy wpisu w pliku app/config/config.yml

Linux

knp_snappy:
    pdf:
        enabled:    true
        binary:     "xvfb-run -a -s \"-screen 0 640x480x16\" -e %kernel.root_dir%/logs/snappy.log wkhtmltopdf"
        options:    []
    image:
        enabled:    false
        binary:     /usr/local/bin/wkhtmltoimage
        options:    []

Windows

knp_snappy:
    pdf:
        enabled:    true
        binary:     "\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\""
        options:    []
    image:
        enabled:    true
        binary:     "\"C:\\Program Files\\wkhtmltopdf\\bin\\wkhtmltopdf.exe\""
        options:    []

Jak używać

Pakiet rejestruje dwie usługi:

  1. knp_snappy.image usługa pozwalająca na generowanie obrazków
  2. knp_snappy.pdf usługa pozwalająca generować pdf-y

Generowanie pdf-a na podstawie adresu URL

$this -> get('knp_snappy.pdf') -> generate('http://porady-it.pl', '/path/file.pdf');

Generowanie pdf-a z widoku

$this -> get('knp_snappy.pdf') -> generateFromHtml(
    $this -> renderView(
        'MyBundle:Foo:bar.html.twig',
        array(
            'some'  => $vars
        )
    ),
    '/path/to/the/file.pdf'
);

Jeśli zaś chcielibyśmy, otrzymywać PDF-a wywołując jakąś akcję kontrolera to wystarczy mała modyfikacji powyższego kodu:


return new Response(
    $this -> get('knp_snappy.image') -> getOutputFromHtml(
        $this -> renderView(
            'MyBundle:Foo:bar.html.twig',
            array(
                'some'  => $vars
            )
        )
    ),
    200,
    array(
        'Content-Type'          => 'application/pdf',
        'Content-Disposition'   => 'attachment; filename="file.pdf"'
    )
);