Showing posts with label Wkhtmltopdf. Show all posts
Showing posts with label Wkhtmltopdf. Show all posts

Saturday, November 10, 2018

Wkhtmltopdf Characters in single line partially cut between pages

In some pages, characters in single line partially cut between pages. When I convert html convert to pdf using pdfkit gem. I am using wkhtmltox-0.12.4_msvc2015-win32 version.
My Pdf getting cut at below image:
Then I added this to my CSS:
table, img, div {page-break-inside: avoid;}
Not it got fixed as below image:

Monday, May 15, 2017

How to add header/footer to multipage pdf on Laravel SnappyPDF WkHtmlToPdf

I am sure you already install WkhtmlToPDF with Snappy in your Laravel project. If not yet please visit the link below to install WkhtmltoPDF in your Laravel project:

Click here.

Now add margin for your page if not added yet because header and footer need some space to visible in PDF header and footer area by editing the file named "config/snappy.php".

<?php
return array(
    'pdf' => array(
        'enabled' => true,
        'binary'  => 'C:\PROGRA~1\wkhtmltopdf\bin\wkhtmltopdf.exe',
        'timeout' => false,
        'options' => array(
            'margin-top'    => 15,
            'margin-right'  => 8,
            'margin-bottom' => 20,
            'margin-left'   => 5
        ),
        'env'     => array(),
    ),
    'image' => array(
        'enabled' => true,
        'binary'  => 'C:\PROGRA~1\wkhtmltopdf\bin\wkhtmltoimage.exe',
        'timeout' => false,
        'options' => array(),
        'env'     => array(),
    )

);


And then append header and footer html in your PDF as follows:

$header_html = file_get_contents(resource_path() . "/" . "pdf-header.html");
$footer_html = file_get_contents(resource_path() . "/" . "pdf-footer.html");

$pdf = SnappyPDF::loadView('home.pdf');
$pdf->setOption('header-html', $header_html);
$pdf->setOption('footer-html', $footer_html);

return $pdf->stream('invoice.pdf');

You have to create two file named "pdf-header.html" and "pdf-footer.html" in your "resource" folder as below.

pdf-header.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body style="border: 1px solid blue;margin-left: 18px;margin-right: 0px;padding:10px">
<div style="color: red">
    THIS IS <b>PAGE HEADER</b>
</div>
</body>

</html>

pdf-footer.html:

<!DOCTYPE html>
<html lang="en">
<head>
    <meta charset="UTF-8">
</head>
<body style="border: 1px solid blue;margin-left: 18px;margin-right: 0px;padding:10px">
<div style="color: red">
    THIS IS <b>PAGE FOOTER</b>
    Page=<span id="page"></span>|
    Total Page=<span id="topage"></span>|
    Date=<span id="date"></span>|
    Time=<span id="time"></span>
</div>
<script type="text/javascript">
    var vars={};
    var x=window.location.search.substring(1).split('&');
    for (var i in x) {
        var z=x[i].split('=',2);
        vars[z[0]] = unescape(z[1]);
    }
    document.getElementById('page').innerHTML = vars.page;
    document.getElementById('topage').innerHTML = vars.topage;
    document.getElementById('date').innerHTML = vars.date;
    document.getElementById('time').innerHTML = vars.time;
</script>
</body>

</html>




PDF will look like below images:




Friday, April 21, 2017

Generate PDFs in Laravel 5.x with Snappy & Wkhtmltopdf

At first we need to install Wkhtmltopdf on our server. To do so we need to add following lines under "require" section on composer.json file as follows:

For 32 bit server:



"require": {
    "h4cc/wkhtmltopdf-i386": "0.12.x",
    "h4cc/wkhtmltoimage-i386": "0.12.x"
}




And for 64 bit server:


"require": {
    "h4cc/wkhtmltopdf-amd64": "0.12.x",
    "h4cc/wkhtmltoimage-amd64": "0.12.x"
}


Now time to install wkhtmltopdf. Open command prompt and navigate to your project location and execute below command to install packages into your project:

composer update h4cc/wkhtmltopdf-i386 --lock
composer update h4cc/wkhtmltoimage-i386 --lock
Or you can download wkhtmltopdf from here. Or you can download also from here.

For windows you do not do anything above. Just download installer for windows version, install it in your machine, done. 

After installation done, need to install "Laravel-Snappy", to do so add following to "composer.json" as follows:


"require": {
    "barryvdh/laravel-snappy": "0.3.x"
}

Open command prompt and navigate to your project location and execute below command to install packages into your project:

composer update barryvdh/laravel-snappy --lock

Next step is to add the line "Barryvdh\Snappy\ServiceProvider::class" to file "config/app.php" under the section "providers" as follows:


'providers' => [Barryvdh\Snappy\ServiceProvider::class]

Its time to add an alias, do the following in "config/app.php" under "aliases" section:


'aliases' => [
    'SnappyPDF' => Barryvdh\Snappy\Facades\SnappyPdf::class
]

Now copy "vendor/barryvdh/laravel-snappy/config/snappy.php" file to "/config" folder and modify as follows:

Location of binary is your wkhtmltopdf installation location. You must careful with the path.

Binary path will be as follows:

For Linux Server with project location: "binary" => ...
base_path('vendor/h4cc/wkhtmltopdf-amd64/bin/wkhtmltopdf-amd64')

For Linux Server with fixed location: "binary" => ...
"/usr/local/bin/wkhtmltopdf-amd64"

And for Windows with installation location: "binary" => ...
'"C:\Program Files\wkhtmltopdf\bin\wkhtmltopdf\bin\wkhtmltopdf.exe"'

<?php
return array(
    'pdf' => array(
        'enabled' => true,
        'binary'  => 'C:\PROGRA~1\wkhtmltopdf\bin\wkhtmltopdf.exe',
        'timeout' => false,
        'options' => array(),
        'env'     => array(),
    ),
    'image' => array(
        'enabled' => true,
        'binary'  => 'C:\PROGRA~1\wkhtmltopdf\bin\wkhtmltoimage.exe',
        'timeout' => false,
        'options' => array(),
        'env'     => array(),
    )

);

Execute following command:
php artisan vendor:publish

Below is a code snippet to stream pdf to browser:

<?php
namespace App\Http\Controllers;

use SnappyPDF;
use Illuminate\Routing\Controller as BaseController;

class HomeController extends BaseController
{
    public function pdf()
    {
        set_time_limit(60 * 5);
        $d1 = array();
        $d2 = array();

        $pdf = SnappyPDF::loadView('home.pdf', compact('d1', 'd2'));

        //Below line code will save pdf to "public" folder
        //$pdf->save('Output.pdf'); die();

        //Below line code to download pdf
        //return $pdf->download('Output.pdf');

        //Below line code will stream PDF to browser
        return $pdf->stream('Output.pdf');
    }

}

And thats it, you have integrated Wkhtmltopdf in your Laravel project using Snappy.

Generate PDF in CakePHP 3.x with CakePDF And Wkhtmltopdf

At first you need to install CakePDF to your project. Add "friendsofcake/cakepdf": "3.2.*" to "composer.json" file under "require" section as follows:

"require": {

    "friendsofcake/cakepdf": "3.2.*"

}

Now open command panel and navigate to project directory and execute:

composer update friendsofcake/cakepdf --lock


Or you can direct execute the command "composer require friendsofcake/cakepdf" to install CakePDF. This command will install a suitable latest version to your project.


Above command will install CakePDF to your project.


Next step is to install wkhtmltopdf.


Download wkhtmltopdf from https://wkhtmltopdf.org/downloads.html.


By default CakePdf expects the wkhtmltopdf binary to be located in /usr/bin/wkhtmltopdf. If you are using wkhtmltopdf in Windows, remove any spaces in the path name. For example use C:/Progra~1/wkhtmltopdf/bin/wkhtmltopdf.exe (Your installation location).



Installation complete, now add the following line to "config/bootstrap.php" file:


Plugin::load('CakePdf', ['bootstrap' => true]);


Configure::write('CakePdf', [

    'engine' => [
        'className' => 'CakePdf.WkHtmlToPdf',
        //'binary' => '/usr/bin/wkhtmltopdf', //LINUX
        'binary' => 'C:\PROGRA~1\wkhtmltopdf\bin\wkhtmltopdf.exe', //WINDOWS
        'options' => [
            'print-media-type' => false,
            'outline' => true,
            'dpi' => 96
        ]
    ],
    'pageSize' => 'Letter',
]);


Configuration options:
  • engine: Engine to be used (required), or an array of engine config options
    • className: Engine class to use
    • binary: Binary file to use (Only for wkhtmltopdf)
    • options: Engine specific options. Currently only for WkHtmlToPdf, where the options are passed as CLI arguments, and for DomPdf, where the options are passed to the DomPdf class constructor.
  • crypto: Crypto engine to be used, or an array of crypto config options
    • className: Crypto class to use
    • binary: Binary file to use
  • pageSize: Change the default size, defaults to A4
  • orientation: Change the default orientation, defaults to portrait
  • margin: Array or margins with the keys: bottom, left, right, top and their values
  • title: Title of the document
  • delay: A delay in milliseconds to wait before rendering the pdf
  • windowStatus: The required window status before rendering the PDF
  • encoding: Change the encoding, defaults to UTF-8
  • download: Set to true to force a download, only when using PdfView
  • filename: Filename for the document when using forced download

Now we can do 3 things with our CakePDF
1. Download PDF
2. Stream PDF to browser
3. Save PDF to our server

Lets go for download & stream PDF:

Add the following code block in "config/router.php" file:


Router::scope('/pdf_download/:id', function (RouteBuilder $routes) {

    $routes->addExtensions(['pdf']);
    $routes->connect('/', ['controller' => 'Pages', 'action' => 'cakePdfDownload']);

});

Now in your "PagesController.php" add below code snippet:


public function cakePdfDownload($name = null)

{
    Configure::write('CakePdf.download', true);
    Configure::write('CakePdf.filename', "MyCustomName.pdf");

}

Now need to create a layout file for pdf. Create "default.ctp" under "Template/Layout/Pdf" directory with following contents:


<?php

use Cake\Core\Configure;
$cakeDescription = 'CakePHP: the rapid development PHP framework';
?>
<!DOCTYPE html>
<html>
<head>
    <?= $this->Html->charset() ?>
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>
        <?= $cakeDescription ?>:
        <?= $this->fetch('title') ?>
    </title>

    <?= $this->Html->meta('icon') ?>

    <?= $this->Html->css('base.css', ['fullBase' => true]) ?>
    <?= $this->Html->css('cake.css', ['fullBase' => true]) ?>
    <?= $this->Html->css('home.css', ['fullBase' => true]) ?>
    <link href="https://fonts.googleapis.com/css?family=Raleway:500i|Roboto:300,400,700|Roboto+Mono" rel="stylesheet">
</head>
<body class="home">

<header class="row">

    <div class="header-image"><?= $this->Html->image('cake.logo.svg') ?></div>
    <div class="header-title">
        <h1>Welcome to CakePHP <?= Configure::version() ?> Red Velvet. Build fast. Grow solid.</h1>
    </div>
</header>
<div class="row">
    <div class="columns large-12">
        <?= $this->fetch('content') ?>
    </div>
</div>
</body>

</html>

'fullBase' => true for create permanent link to resources.


Now create a file named "cake_pdf_download.ctp" under "Template/Pages/Pdf" directory with any content.


You are done, you browse "http://localhost/cake/pdf_download/invoice.pdf" then a pdf will be downloaded because we set "Configure::write('CakePdf.download', true);" if we set false here as "Configure::write('CakePdf.download', false);" then PDF will not be downloaded but will be rendered in browser itself.






Now go for save PDF to our server:


public function cakePdf()

{
    $CakePdf = new \CakePdf\Pdf\CakePdf();
    $CakePdf->template('cake_pdf', 'default');
    $CakePdf->viewVars($this->viewVars);
    $pdf = $CakePdf->write(APP . 'Files' . DS . 'Output.pdf');
    echo $pdf;die();

}

And finally you are done CakePDF with wkhtmltopdf.