Skip to content
CODE THE PIXEL
CakePHP

CakePHP 4 Print PDF Using CakePDF

Asyraf Wahi Anuar Updated 6 min read

This tutorial will show how to use the CakePDF plugin to generate a PDF file. This tutorial will use DOMPDF as an example of the generator engine. Basically, generating PDF is useful for those who are working with a system that prints or produce correspondence or document related task.

This tutorial may be outdated

It was last reviewed 4 years ago. Some steps may differ in newer versions.

Tech stack

  • CakePHP 4.x

This tutorial will show how to use the CakePDF plugin to generate a PDF file. This tutorial will use DOMPDF as an example of the generator engine. Basically, generating PDF is useful for those who are working with a system that prints or produce correspondence or document related task.

Download and Load CakePDF Plugin

Download CakePDF plugin via composer:

Terminal
composer require friendsofcake/cakepdf

Load the plugin using the console:

Terminal
bin/cake plugin load CakePdf

or manually add the following code to ...\src\Application.php

src/Application.phpPHP
$this->addPlugin('CakePdf');

PDF Engine

The plugin does not include the PDF generator engine. You need to download the engine. Depending on what engine you want to use, you need to download them to your project. DomPdf, Mpdf and Tcpdf can be installed via composer using one of the following commands:

Terminal
composer require dompdf/dompdfcomposer require tecnickcom/tcpdfcomposer require mpdf/mpdf

You also can use WkHtmlToPdf which can be downloaded from the webpage.

Engine Configuration

At the end of the file, load the following codes. Replace the "Dompdf" engine with the one you intend to use yourself.

config/bootstrap.phpPHP
Configure::write('CakePdf', [
    'engine' => [
        'className' => 'CakePdf.DomPdf',
        'options' => [
            'isRemoteEnabled' => true
        ]
    ],
    'margin' => [
        'bottom' => 10,
        'left' => 10,
        'right' => 10,
        'top' => 10
    ],
    'orientation' => 'portrait',
    'download' => true
]);

If use WkHtmlToPdf, specify the binary full path:

PHP
'binary' => 'C:\wkhtmltopdf\bin\wkhtmltopdf.exe'

Controller

Depending on which controller you need to generate the PDF, create a new public function pdf:

PHP
public function pdf($id = null)
{
    $this->viewBuilder()->enableAutoLayout(false); 
    $report = $this->Reports->get($id);
    $this->viewBuilder()->setClassName('CakePdf.Pdf');
    $this->viewBuilder()->setOption(
        'pdfConfig',
        [
            'orientation' => 'portrait',
            'download' => true, // This can be omitted if "filename" is specified.
            'filename' => 'Report_' . $id . '.pdf' //// This can be omitted if you want file name based on URL.
        ]
    );
    $this->set('report', $report);
}

If you want to use the title as the filename, use the following codes:

PHP
'filename' => \Cake\Utility\Text::slug($report->title) . '-' . __('Report') . '.pdf'

Template

Create the view templates in a 'pdf' subdir, for instance, templates/Reports/pdf/pdf.php and add the following codes into pdf.php file

Reports/pdf/pdf.phpPHP
<!DOCTYPE html>
<html>
<head>
<title>PDF</title>
<style>
@page {
    margin: 0px 0px 0px 0px !important;
    padding: 0px 0px 0px 0px !important;
}
</style>
</head>
<body>
<?= h($report->title) ?>
</body>
</html>

In your view.php file, add the following code to call the pdf page:

PHP
<?= $this->Html->link(__('Download PDF'), ['action' => 'pdf', $report->id ]) ?>

Insert Image in PDF

It required fullbase set to true as follows:

PHP
<?= $this->Html->image('myImage.png', ['fullBase' => true]); ?>

Insert CSS in PDF

It required fullbase set to true as follows:

PHP
<?= $this->Html->css('pdf.css', ['fullBase' => true]) ?>

Now you should be able to generate the pdf file and download it. For CSS, just create and link it to the pdf template or just add it to the style.

Save PDF to Server

To generate and save the PDF into a webserver, use the following code:

PHP
public function pdf($id = null)
{
    $this->viewBuilder()->enableAutoLayout(false); 
    $report = $this->Reports->get($id);
    $this->viewBuilder()->setClassName('CakePdf.Pdf');
    $this->viewBuilder()->setOption(
        'pdfConfig',
        [
            'orientation' => 'portrait',
            'download' => true, // This can be omitted if "filename" is specified.
            'filename' => 'Report_' . $id . '.pdf' // This can be omitted if you want file name based on URL.
        ]
    );
	//Write and Save PDF to folder
	$CakePdf = new \CakePdf\Pdf\CakePdf();
	$CakePdf->template('report', 'default');
	$CakePdf->viewVars([
		'title' => $report->title, //variables eg
		'body' => $report->body,
	]);
	// Get the PDF string returned
	$pdf = $CakePdf->output();
	// Or write it to file directly
	$pdf = $CakePdf->write('files' . DS . 'pdf' . DS . $id . '.pdf'); //stored in ...webroot/files/pdf/1.pdf
	
    $this->set('report', $report, 'title', 'body');
}

Create default template at ...\templates\layout\pdf\default.php and use the viewVars eg:

templates/layout/pdf/default.phpPHP
<!DOCTYPE html>
<html>
<head>
<title>PDF</title>
<?php
use Cake\Routing\Router;
?>
<style>
@page {
	margin-top: 50px !important;
	margin-bottom: 50px !important;
	margin-right: 50px !important;
	margin-left: 50px !important;
    padding: 0px 0px 0px 0px !important;
}
body{
	font-family: 'Roboto', sans-serif;
}
</style>
</head>
<body>
Hello<br/>
<?= $title; ?>
<br/>
<?= $body; ?>
</body>
</html>

Email Saved PDF as Email Attachment

To email the saved PDF as an attachment, use the following code. Read more about CakePHP 4 Email.

PHP
public function pdf($id = null)
{
    $this->viewBuilder()->enableAutoLayout(false); 
    $report = $this->Reports->get($id);
    $this->viewBuilder()->setClassName('CakePdf.Pdf');
    $this->viewBuilder()->setOption(
        'pdfConfig',
        [
            'orientation' => 'portrait',
            'download' => true, // This can be omitted if "filename" is specified.
            'filename' => 'Report_' . $id . '.pdf' //// This can be omitted if you want file name based on URL.
        ]
    );
	//Write and Save PDF to folder
	$CakePdf = new \CakePdf\Pdf\CakePdf();
	$CakePdf->template('report', 'default');
	$CakePdf->viewVars([
		'title' => $report->title, //variables eg
		'body' => $report->body,
	]);
	// Get the PDF string returned
	$pdf = $CakePdf->output();
	// Or write it to file directly
	$pdf = $CakePdf->write('files' . DS . 'pdf' . DS . $id . '.pdf');
	
	//Email with attachment
	$mailer = new Mailer('default');
	$mailer
		->setTransport('smtp');
		->setAttachments(['files' . DS . 'pdf' . DS . $id . '.pdf']); //get saved PDF file
		->setFrom(['noreply@codethep!xel.com' => 'Code The Pixel'])
		->setTo('receiver@example.com') //receiver email
		->setEmailFormat('html')
		->setSubject('Report') //email subject
		->deliver('Report in PDF'); //content

		return $this->redirect($this->referer());
	
    $this->set('report', $report, 'title', 'body');
}

That all. Happy coding :)

Did this tutorial help?

241 readers found this helpful

Comments

No comments yet. Questions about this tutorial are welcome here: the answer helps the next reader too.

Leave a comment

Markdown works: `code`, ``` blocks, **bold**, links.

First comments are reviewed before they appear.

CakePHP

Using Bahasa Melayu Table Names in CakePHP

Learn how to use Bahasa Melayu table names like "pengguna" in CakePHP while following the framework’s naming conventions. Includes tips for using the Bake tool and avoiding pluralization issues.

5 min read

Tools & Software

Formatting PHP in VSCode Using Prettier and PHP Intelephense

Learn how to set up Visual Studio Code (VSCode) for automatic PHP file formatting using the Prettier and PHP Intelephense extensions. This step-by-step tutorial will help you maintain a clean and organised codebase, enhancing your PHP development experience.

2 min read