8

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.

luis.ap.uyen
  • 1,314
  • 1
  • 11
  • 29

3 Answers3

14

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!

luis.ap.uyen
  • 1,314
  • 1
  • 11
  • 29
13

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;
}
Jake Jackson
  • 703
  • 5
  • 10
  • 2
    There's a timeout error. Seems that it takes a lot of time to process it. mPDF seems too slow when processing images. – luis.ap.uyen May 11 '18 at 06:13
  • I've also checked that if I use a low resolution background image (which is not desirable, because it will be awful to print) mPDF handles it within the timeout deadline, but it breaks my layout apart anyway :( – luis.ap.uyen May 11 '18 at 06:19
  • 1
    This worked for me, where is `background-image-resize` documented? – Raul Sauco Mar 14 '20 at 12:36
  • @RaulSauco https://mpdf.github.io/css-stylesheets/supported-css.html – Chnossos Apr 30 '21 at 12:53
  • just show image logo as sidebar then use one background: url('/full/path/to/image/background_300dpi.png'); background-repeat: repeat-y; – Ghanshyam Nakiya Sep 22 '22 at 12:16
0

You view in example file: example54_new_mPDF_v5-1_features_gradients_and_images.php

<?php


$path = (getenv('MPDF_ROOT')) ? getenv('MPDF_ROOT') : __DIR__;
require_once $path . '/vendor/autoload.php';

$mpdf = new \Mpdf\Mpdf();

//==============================================================
$html = '
<style>
table {
    background: url(\'assets/bayeux1.jpg\') repeat scroll left top;
}
.table1 tr.thisrow1 {
    background-image-resolution: 300dpi;

}
.table1 tr.thisrow1 td {
    height: 28mm;
}
.table1 tr.thisrow2 {
    background-image: none;
    background: -moz-linear-gradient(left, #c7Fdde 20%, #FF0000 );
    background: -webkit-gradient(linear, left bottom, left top, color-stop(0.29, rgb(90,83,12)), color-stop(0.65, rgb(117,117,39)), color-stop(0.83, rgb(153,153,67)));
}
</style>

<table class="table1">
<tbody>
    <tr><td>Row 1</td><td>This is data</td><td>This is data</td></tr>
    <tr class="thisrow1">
        <td>This row has</td>
        <td>a background-image</td>
        <td>of the bayeux tapestry</td>
    </tr>
    <tr><td><p>Row 3</p></td><td><p>This is long data</p></td><td>This is data</td></tr>
    <tr class="thisrow2"><td>This row has</td><td>a gradient set</td><td>which spans all 3 cells</td></tr>
    <tr><td>Row 5</td><td>Also data</td><td>Also data</td></tr>
</tbody>
</table>


';

$mpdf->WriteHTML($html);

$mpdf->Output(); exit;
nthaih
  • 71
  • 3