A simple library that lets you convert webpages or HTML into PDF files using Chromium-powered browsers.
Here's quick example, how it works:
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setHtml('<h1>Hello world!</h1>')
->save('/path/to/your/file.pdf');
In case you want to convert web page into the PDF, you can use setUrl()
instead of setHtml()
:
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setUrl('https://github.com')
->save('/path/to/your/file.pdf');
.. if you need specific version of Chrome, or don't want to use locally downloaded Chromium, make use
of setChromiumPath
method.
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setUrl('https://github.com')
->setChromiumPath('/path/to/your/chrome')
->save('/path/to/your/file.pdf');
Laravel usage with blade templates
$snappdf = new \Beganovich\Snappdf\Snappdf();
$fields = [...];
// Render method returns HTML string (template compile)
$html = view('pdf.warranty', compact('fields'))->render();
$pdf = $snappdf
->setHtml($html)
->save('/path/to/your/file.pdf');
If none of previously listed option fits your needs, you can also set path to executable Chromium with environment variable.
SNAPPDF_EXECUTABLE_PATH=/path/to/your/chrome
This is example for Nginx configuration (server block) (thanks @cdahinten):
fastcgi_param SNAPPDF_EXECUTABLE_PATH '/usr/bin/chromium';
fastcgi_param SNAPPDF_SKIP_DOWNLOAD true;
If you need to generate PDF only, without saving it, make use of generate()
:
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setUrl('https://github.com')
->setChromiumPath('/path/to/your/chrome')
->generate();
file_put_contents('my.pdf', $pdf); // for local storage
Storage::disk('s3')->put('my.pdf', $pdf); // for remote storage
Note: setChromiumPath
has highest priority. Second one is environment variable & third local download.
While the default arguments should work in most use cases, but it is possible to specify which arguments to use:
Using the addChromiumArguments
Method:
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setUrl('https://github.com')
->setChromiumPath('/path/to/your/chrome')
->addChromiumArguments('--single-process --tls1')
->generate();
If you want to remove single argument, you can make use of clearChromiumArgument
.
$snappdf = new \Beganovich\Snappdf\Snappdf();
$snappdf->getChromiumArguments(); // ['--headless', '--disable-gpu', '--disable-translations']
$snappdf->clearChromiumArgument('--headless'); // ['--disable-gpu', '--disable-translations']
In the event you want to override the default arguments, you can use the the SNAPPDF_EXECUTABLE_ARGUMENTS
environmental variable.
NOTE: The --print-to-pdf
argument is always added, and the --virtual-time-budget
argument is added whenever the waitBeforePrinting
method is called.
To clear all arguments you can use the clearChromiumArguments
method.
$snappdf = new \Beganovich\Snappdf\Snappdf();
// $snappdf->getChromiumArguments() = [ '--headless', '--disable-gpu', ... ]
$snappdf->setChromiumPath('/path/to/your/chrome')
->clearChromiumArguments();
// $snappdf->getChromiumArguments() = []
If you want to use snappdf as command-line tool, make use of "convert" command:
./vendor/bin/snappdf convert --url https://github.com /path/to/save.pdf
In case you want to convert HTML:
./vendor/bin/snappdf convert --html "<h1>Hello world!</h1>" /path/to/save.pdf
You can also specify custom binary location (if you don't use locally downloaded Chromium revision):
./vendor/bin/snappdf convert --url https://github.com --binary /usr/bin/google-chrome /path/to/save.pdf
Main benefit and reason why this library exists is the speed of generating PDFs. It communicates directly with browser itself and it takes less than .5s to generate PDFs (with cold start). This was tested on mid-range laptop with i5-5300U and average SSD.
➜ snappdf git:(master) ./vendor/bin/phpunit --testdox --filter=testGeneratingPdfWorks
PHPUnit 9.5.0 by Sebastian Bergmann and contributors.
Snappdf (Test\Snappdf\Snappdf)
✔ Generating pdf works
Time: 00:00.199, Memory: 6.00 MB
OK (1 test, 1 assertion)
➜ snappdf git:(master) ./vendor/bin/phpunit --testdox --filter=testGeneratingPdfWorks
PHPUnit 9.5.0 by Sebastian Bergmann and contributors.
Snappdf (Test\Snappdf\Snappdf)
✔ Generating pdf works
Time: 00:00.171, Memory: 6.00 MB
OK (1 test, 1 assertion)
Composer is recommended way of installing library:
composer require beganovich/snappdf
snappdf can download & use local revision of Chromium. To achieve that, you can use:
./vendor/bin/snappdf download
You can find local downloads/revisions in %projectRoot%/vendor/beganovich/snappdf/versions
.
Local revision will be used only when you don't provide path using setChromiumPath()
.
Note: snappdf will download & use latest build of Chromium. Since Chromium itself doesn't have stable or unstable release, browser itself can be buggy or possibly broken. We don't take any responsibility for that. If security & stability is your top priority, please install Google Chrome stable version & point package to use that.
If you need to dynamically skip the download, make use of SNAPPDF_SKIP_DOWNLOAD
environment variable.
Make sure your system has installed all required dependencies. Thanks Puppeteer ❤
In case you need much more complex software to perform operations with headless browser go for Spatie's Browsershot. It's fantastic package. Purpose of snappdf is to be really minimal & only focus on making PDFs.
Also, snappdf doesn't need Node installed to operate.
You can use waitBeforePrinting()
to set maximum delay before running the print. Use case for this would be if you need to
make an Ajax call or wait for library (e.g. charts) to load before printing.
Note: Values provided are in milliseconds. One really important note is: If you delay load by 10 seconds (10000) it won't delay PDF rendering itself by 10s, but it will give time for libraries or Ajax calls to finish & then action the printing.
TLDR; If you set delay loading to 10 seconds & Ajax call takes 2 seconds to complete, PDF rendering will start immediately after Ajax call is completed (after 2 seconds), and it won't wait 10 seconds.
Starting with version 3, snappdf will automatically get rid of temporary files. If you still want to keep them, you can do it using setKeepTemporaryFiles
method.
$snappdf = new \Beganovich\Snappdf\Snappdf();
$pdf = $snappdf
->setUrl('https://github.com')
->setChromiumPath('/path/to/your/chrome')
->setKeepTemporaryFiles(true)
->generate();
file_put_contents('my.pdf', $pdf);
The MIT License (MIT).