phpfpdffpdi

PHP Fpdf library: Embedding logo image in the header for every page in the PDF


I am working on a PHP project. I need to generate the PDF using the FPDF library, http://www.fpdf.org/ in my application. But I am having an issue with embedding the logo image in the header for every page.

Here is my code:

    $fontFamily = "Helvetica";
    $pdf = new Fpdi();
    $pdf->SetFont($fontFamily,'',8);
    $pdf->AliasNbPages();
    $pdf->AddPage();
    //logo at the top of the page.
    $pdf->Image('img/logo.png', 125, 10, 73, 15);
    //loop through the array and render the list
    for($i=1;$i<=100;$i++)
        $pdf->Cell(0,5,'Printing line number '.$i,0,1);
    $pdf->Output();

As you can see in my code, I render the logo in the header following the example in the documentation. That adds the logo in the beginning of the PDF. But there is an issue with that. As you can see, I am looping through the array and rendering the list in the PDF. I don't know how long it is going to be since the data is going to be dynamic.

But it automatically creates new page for the list if needed. But the thing is the newly created page (second) page does not have the header logo at the top. How can I embed the logo in the header for the every page and it will be automatically added for the new pages?


Solution

  • You need to define a Header() method that will be run automatically by FPDF each time a new page is added (either manually with AddPage(), or automatically).

    To do so, you need to subclass the FPDF class, and create another class with an appropriate Header() method:

    class WaiYanHeinPDF extends FPDF {
        public function Header() {
            parent::Header();
            // Add the logo here.
        }
    }
    

    See the relevant manual page.


    I have developed such a subclass, that allows specifying the header function at runtime. I had forgotten that the vanilla FPDF does not have the setHeader() function: apologies for that. This is what I did:

    class MyPDF extends FPDF {
    
        private $onHeader;
    
        public function setHeader(Callable $func) {
            $this->onHeader = $func;
            return $this;
        }
    
        public function Header() {
            parent::Header();
            if ($this->onHeader) {
                call_user_func($this->onHeader, $this);
            }
        }
    }
    

    Then and only then I can just do (hence my previous, wrong answer):

    $MyPdf->setHeader(function($pdf) {
        ...
    });
    

    without creating a new class for each different PDF I need. I just create different instances of MyPDF().