Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

mPDF: use background image for full page

Tags:

php

mpdf

I need to generate invoices with mPDF, and they all will have a header, a footer, and the same background image which has to cover the whole page.

I've seen other solutions on the net but none worked for me.

These are several attempts, all of them lead to failure (image not being displayed, 50* error or image covering part of the content when using images):

1- Using external CSS file and injecting it as CSS content

$pdf = new mPDF('es', 'A4', 0, '', 5, 5, 0, 0, 0, 0, 'P');

$pdf->useSubstitutions=false;
$pdf->setAutoTopMargin = 'stretch';
$pdf->SetDisplayMode('fullpage');


$css = file_get_contents('./styles.css');
$cabecera = file_get_contents('./header.html');
$cuerpo = file_get_contents('./body.html');
$pie = file_get_contents('./footer.html');

$pdf->SetHTMLHeader($cabecera);
$pdf->SetHTMLFooter($pie);
$pdf->WriteHTML($css, 1);

$pdf->WriteHTML($cuerpo, 2);

$pdf->Output();

And the styles.css file:

body {
    background-image: url('background_300dpi.png') ;
}

This throws a timeout error. If I use a low resolution image background, it works, but it breaks my layout.

2- Trying to set the background image with SetDefaultBodyCSS

$pdf = new mPDF('es', 'A4', 0, '', 5, 5, 0, 0, 0, 0, 'P');

$pdf->useSubstitutions=false;
$pdf->setAutoTopMargin = 'stretch';
$pdf->SetDisplayMode('fullpage');


$cabecera = file_get_contents('./cabecera.html');
$cuerpo = file_get_contents('./cuerpo.html');
$pie = file_get_contents('./pie.html');

$pdf->SetHTMLHeader($cabecera);
$pdf->SetHTMLFooter($pie);

$pdf->SetDefaultBodyCSS('background', "url('background_300dpi.png')");
$pdf->SetDefaultBodyCSS('background-image-resize', 6);

$pdf->WriteHTML($cuerpo, 2);

$pdf->Output();

Timeout error too. It does work if I use a low resolution image. But this is not a good solution to print, because there are small letters in the letterhead which is included in the background image.

3 - Trying to use images (the background image is split into a top letterhead and a bottom image) instead of an only background image, and setting margin constraints to false

$pdf = new mPDF('es', 'A4', 0, '', 5, 5, 0, 0, 0, 0, 'P');

$pdf->useSubstitutions=false;
$pdf->setAutoTopMargin = 'stretch';
$pdf->SetDisplayMode('fullpage');


$cabecera = file_get_contents('./cabecera.html');
$cuerpo = file_get_contents('./cuerpo.html');
$pie = file_get_contents('./pie.html');

$pdf->SetHTMLHeader($cabecera);
$pdf->SetHTMLFooter($pie);

$pdf->WriteHTML($cuerpo, 2);

$pdf->Image('miramar/background_top.png', 0, 0, 210, 28.5, 'png', '', true, false);
$pdf->Image('miramar/background_bottom.png', 0, 259, 210, 38, 'png', '', true, false, false, false);

$pdf->Output();

There's no timeout in this case, but the footer image makes that some content included in the footer is gone.

Anyone has an idea on how to achieve it?

Another question: does mPDF support vector images for backgrounds? I might use the background image as an SVG file.

like image 868
luis.ap.uyen Avatar asked May 10 '18 15:05

luis.ap.uyen


2 Answers

Use the @page CSS selector instead of body to set the background. Then add the property background-image-resize: 6; to ensure the image covers the full width and height of each page.

In styles.css:

@page {
    background: url('/full/path/to/image/background_300dpi.png') no-repeat 0 0;
    background-image-resize: 6;
}
like image 179
Jake Jackson Avatar answered Oct 25 '22 22:10

Jake Jackson


I got it! As I guessed later, having that I could use the background image as a vector image (SVG) I could do it this way.

This is the code:

$pdf = new mPDF('es', 'A4', 0, '', 5, 5, 0, 0, 0, 0, 'P');

$pdf->useSubstitutions=false;
$pdf->setAutoTopMargin = 'stretch';
$pdf->SetDisplayMode('fullpage');

$cabecera = file_get_contents('./cabecera.html');
$cuerpo = file_get_contents('./cuerpo.html');
$pie = file_get_contents('./pie.html');

$pdf->SetHTMLHeader($cabecera);
$pdf->SetHTMLFooter($pie);

$pdf->SetDefaultBodyCSS('background', "url('./background_image.svg')");
$pdf->SetDefaultBodyCSS('background-image-resize', 6);

$pdf->WriteHTML($cuerpo, 2);

$pdf->Output();

With SVG it works like a charm and it's fast!

like image 32
luis.ap.uyen Avatar answered Oct 25 '22 22:10

luis.ap.uyen