11

I am new to PHP and am having a bit of a hard time with using FPDI when it comes to inserting multiple pages.

I have a .pdf file which consists of 3 pages. I ended up saving page 1 as a separate page out of the 3 and that worked with my code, but that is because my code is meant only for 1 page. When I change it back to the 3 page file, it gives me an internal server error.

This is the code which I am using:

<?php

require_once('prog/fpdf.php');
require_once('prog/fpdi.php');

// initiate FPDI
$pdf = new FPDI();

// add a page
$pdf->AddPage();

// set the source file
$pdf->setSourceFile("apps/Par.pdf");

// import page 1
$tplIdx = $pdf->importPage(1);

// use the imported page and place it at point 10,10 with a width of 100 mm
$pdf->useTemplate($tplIdx, null, null, 0, 0, true);

// font and color selection
$pdf->SetFont('Helvetica');
$pdf->SetTextColor(200, 0, 0);

// now write some text above the imported page
$pdf->SetXY(40, 83);
$pdf->Write(2, 'THIS IS JUST A TEST');


$pdf->Output();

I am not sure how to turn this code into having the ability to see all 3 pages. Please help me out who ever can.

hiter202
  • 109
  • 1
  • 2
  • 6

6 Answers6

26

The setSourceFile() method will return the page count of the document you'd set. Just loop through this pages and import them page by page. You example for all pages would look like:

<?php
require_once('prog/fpdf.php');
require_once('prog/fpdi.php');

// initiate FPDI
$pdf = new FPDI();

// set the source file
$pageCount = $pdf->setSourceFile("apps/Par.pdf");

for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
    $tplIdx = $pdf->importPage($pageNo);

    // add a page
    $pdf->AddPage();
    $pdf->useTemplate($tplIdx, null, null, 0, 0, true);

    // font and color selection
    $pdf->SetFont('Helvetica');
    $pdf->SetTextColor(200, 0, 0);

    // now write some text above the imported page
    $pdf->SetXY(40, 83);
    $pdf->Write(2, 'THIS IS JUST A TEST');
}

$pdf->Output();

Regarding the "internal server" you should enable your error reporting:

error_reporting(E_ALL);
ini_set('display_errors', 1);

...or simply check your php error logs for details.

Jan Slabon
  • 4,736
  • 2
  • 14
  • 29
  • 2
    Update: On the latest version of FPDI (2.2) the order of parameters of `useTemplate()` changed. Use: `$pdf->useTemplate($tplIdx, 0, 0, null, null, true);` – Havenard Apr 07 '19 at 21:00
  • 1
    @Havenard: It's not the order but the default values as documentated [here](https://manuals.setasign.com/fpdi-manual/v2/migrating/#index-7). IIRC internally this doesn't make a change at all? In v2 you also can pass an array of options now, so that it will look like `$pdf->useTemplate($tplIdx, ['adjustPageSize' => true]);` – Jan Slabon Apr 08 '19 at 16:09
  • 1
    Well I post this because it does make a difference, FPDI throws a fatal error because `x` and `y` cannot be `null` (`width` and `height` can). -- At least in the Composer version of the library, I noticed there are variants and didn't test them. – Havenard Apr 08 '19 at 18:36
  • @Havenard: You're right! This was a BC change - that's why we documentated it in the migration guide. – Jan Slabon Apr 09 '19 at 09:16
  • I have a related issue. I have a 1-x page document, and sometimes I need to print out 2 copies of the document, with some of the content static and the other dynamic. I sort of know how to do that, but looking for a way to append a second copy of my PDF document to the original. – SScotti Nov 20 '20 at 07:19
  • @SScotti Nothing stops you from doing this (just restart your iteration). If you have a problem with your code, open a new question and please don't use a comment on an answer for a new question. – Jan Slabon Nov 20 '20 at 09:46
  • @JanSlabon Thanks. Actually figured out how to deal with that. A little complicated because I have documents that can have 1-n pages, and then 1-n copies of each document. Works OK though. Thanks. – SScotti Nov 20 '20 at 16:50
  • Thank you so much – Mirtov Jan 17 '22 at 22:31
6

It works for me:

<?php

require_once('fpdf/fpdf.php');
require_once('fpdi/src/autoload.php');

use \setasign\Fpdi\Fpdi;

$pdf = new FPDI();
// get the page count
$pageCount = $pdf->setSourceFile('pdf_file.pdf');
// iterate through all pages
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
    // import a page
    $templateId = $pdf->importPage($pageNo);
    // get the size of the imported page
    $size = $pdf->getTemplateSize($templateId);

    // create a page (landscape or portrait depending on the imported page size)
    if ($size[0] > $size[1]) {
        $pdf->AddPage('L', array($size[0], $size[1]));
    } else {
        $pdf->AddPage('P', array($size[0], $size[1]));
    }

    // use the imported page
    $pdf->useTemplate($templateId);

    $pdf->SetFont('Helvetica');
    $pdf->SetXY(5, 5);
    $pdf->Write(8, 'A complete document imported with FPDI');
}

$pdf->Output();

Change array($size['w'], $size['h']) for array($size[0], $size[1])

Chalén
  • 61
  • 1
  • 4
4
<?php
require_once('fpdf/fpdf.php');
require_once('fpdi/fpdi.php');

// initiate FPDI
$pdf = new FPDI();

// get the page count
$pageCount = $pdf->setSourceFile('Laboratory-Report.pdf');
// iterate through all pages
for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
// import a page
$templateId = $pdf->importPage($pageNo);
// get the size of the imported page
$size = $pdf->getTemplateSize($templateId);

// create a page (landscape or portrait depending on the imported page size)
if ($size['w'] > $size['h']) {
    $pdf->AddPage('L', array($size['w'], $size['h']));
} else {
    $pdf->AddPage('P', array($size['w'], $size['h']));
}

// use the imported page
$pdf->useTemplate($templateId);

$pdf->SetFont('Helvetica');
$pdf->SetXY(5, 5);
$pdf->Write(8, 'A complete document imported with FPDI');
}

// Output the new PDF
$pdf->Output();    
0

you can do this by old solution but here i am explaining how to use it.

# Add 2 page
$pdf->AddPage(); 
$tplIdx2 = $pdf->importPage(2);
$pdf->useTemplate($tplIdx2); 
$pdf->SetAutoPageBreak(true, 5); # optional line

here you have to note that i am adding AddPage() code that adds new page into PDF. Add Page always comes first. it is required.

importPage(Page_number) imports a page into current page of PDF.

pankaj
  • 1
  • 17
  • 36
0

This worked perfectly for me. Laravel implementation. And this only writes on the page you want not every page

use setasign\Fpdf\Tpdf\Fpdf;
use setasign\Fpdi\Fpdi;

class SignDocumentsController extends Controller
{
    public function signPDF(Request $data)
    {
        
        $pdf = new Fpdi();
        
        $pageCount = $pdf->setSourceFile($data["sourceFile"]);
        
        for ($pageNo = 1; $pageNo <= $pageCount; $pageNo++) {
            $tplIdx = $pdf->importPage($pageNo);
            $pdf->AddPage();
            $pdf->useTemplate($tplIdx, 5, 5, 205);

            $pdf->SetFont('Times');
            $pdf->SetTextColor(0, 0, 0);
            
            if($pageNo==$data["pageNumber"]){
                $pdf->Image($data["signitureImg"],$data["x"],$data["y"],$data["w"],$data["h"],$data["pictureType"]);
                $x = $data["x"]+1;
                $y = $data["y"]+$data["h"]+1;
                $pdf->SetXY($x,$y);
                $pdf->Write(0, date("Y-m-d H:i:s"));
            }
            $filename=$data["outputFile"];
        }
        $pdf->Output($filename,'F');
        
        return response()->json([

            "success"=>true,
            "responseBody" => [
                "change_status" =>"Success"
            ]
                    ], 201);

        

    }

}

The json post request data is:

{
    "sourceFile":"/home/courage/Documents/TM 2020.pdf",
    "outputFile":"/home/courage/Documents/Signed.pdf",
    "pageNumber":"3",
    "signitureImg":"/home/courage/Downloads/signature.png",
    "x":"85",
    "y":"230",
    "w":"30",
    "h":"11",
    "pictureType":"png"
}
0

Here is my solution. This works for me.

$pdf = new Fpdi();

$sourceFilePages = $pdf->setSourceFile($sourceFile);

    for($pageNo = 1; $pageNo <= $sourceFilePages; $pageNo++){

        $template = $pdf->importPage($pageNo);

        $pdf->AddPage();
       
        // $adjustPageSize needs to be set to true if you need to have the original PDF page dimensions 
        $pdf->useTemplate($template, 0, 0, null, null, true);


        if ($stampFirstPageOnly){
            if ($pageNo == 1){
                // stamping only the first page
                $pdf->Image($stampFile, stampXCoord, $stampYCoords, $stampWidth, $stampHeight);
            }
        }
        else{
            // stamping all the pages
            $pdf->Image($stampFile, $stampXCoord, $stampYCoords, $stampWidth, $stampHeight);
        }
    }

// pdfOutputMethod "I" -> Browser Inline, "D" -> Force Download, "F" -> Save to Disk
$pdf->Output($pdfOutputMethod, $fileName);
Dula
  • 1,276
  • 5
  • 14
  • 23