Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

PHP - How to use mPDF to merge PDFs

I will start out by saying that I can generate PDFs just fine with mPDF, but for the life of me, I can't get it to merge an existing PDF with the PDF it just generated.

What I need to figure out is how to append/add the existing PDF to the newly generated PDF. I've tried using the mPDF methods for importing pages, but all I can get is an error like:

mPDF error: Cannot open '/downloads/test.pdf'.

The above message is ambiguous and unclear as to WHY it can't open the file... Here's the code I'm using to try and merge PDFs:

 include_once("./pdf/mpdf/mpdf.php");

 $output_file = $_GET['output_file'];
 $url = $_GET['input_file'];
 $technical_drawing = $_GET['tech_drawing'];

 $html = file_get_contents($url);

 $mpdf = new mPDF('utf-8','Letter','','',0,0,0,0,0,0,'P');
 $mpdf->SetImportUse(); 

 $pagecount = $mpdf->SetSourceFile($technical_drawing);
 $tplIdx = $mpdf->ImportPage($pagecount);
 $mpdf->UseTemplate($tplIdx);

 $mpdf->WriteHTML($html);
 $mpdf->Output($output_file, 'D');

 exit;

$output_file will be the filename shown to the user. $url is the HTML we're writing into the file during PDF generation. $technical_drawing is a relative path to a PDF that we want to append/merge with the generated PDF.

I understand I could use something like ghostscript, but I don't have that type of access on the client's server.

Let me know if anyone has found a solution to this using mPDF or if I'm S.O.L. and need to find another library to do PDF merging. I am really looking for solutions or suggestions, but not just links to another library. I've exhausted what I can find in Google or in mPDF's documentation that describes the error I'm having.

EDIT: changed mPDF error from http://example.com/pdf/example.pdf to '/downloads/test.pdf'.

EDIT_2: Code has been fixed to take relative path.

Here's final working code. Bonus if anyone knows how to specify the order of writing HTML to PDF document, importing page as last page (with custom page size different from that of the HTML).

    include_once("./pdf/mpdf/mpdf.php");

    $output_file = 'test-' . $_GET['output_file'];
    $url = $_GET['input_file'];
    $technical_drawing = $_GET['tech_drawing'];

    $html = file_get_contents($url);


    if(!file_exists($technical_drawing)) {
      $mpdf = new mPDF('utf-8','Letter','','',0,0,0,0,0,0,'L');
    } else {
      $mpdf = new mPDF('utf-8','A3-L','','',0,0,0,0,0,0,'L');

      $mpdf->SetImportUse(); 

      $pagecount = $mpdf->SetSourceFile($technical_drawing);
      $import_page = $mpdf->ImportPage();

      $mpdf->UseTemplate($import_page);

      // Add Last page
      $mpdf->AddPageByArray(array(
        'orientation' => 'P',
        'ohvalue' => 1,
        'ehvalue' => -1,
        'ofvalue' => -1,
        'efvalue' => -1,
        'newformat' => 'Letter'
      ));
    }

    $mpdf->WriteHTML($html);
    $mpdf->Output($output_file, 'D');

    exit;
like image 682
cvanorman Avatar asked Oct 16 '14 21:10

cvanorman


3 Answers

This code is work with mpdf 8.0.7 with php 7.4.

              Mfiles = array();

             //Multiple pdf store in Mfiles array with full path.               
             array_push($Mfiles,'/assets/'.$pdfname.'.pdf');

                            
             $Mpath = 'Give file path with have you need to merge all pdf';

             // after loop we start this code
              if($Mfiles) 
                {
                  $filesTotal = sizeof($Mfiles);
                  $fileNumber = 1;
                  
                  if (!file_exists($Mpath)) 
                  {
                      $handle = fopen($Mpath, 'w');
                      fclose($handle);
                  }
                  foreach ($Mfiles as $fileName) 
                  {
                    if (file_exists($fileName)) 
                    {
                      $pagesInFile = $pdf->SetSourceFile($fileName);
                      for ($i = 1; $i <= $pagesInFile; $i++) 
                      {
                        $tplId = $pdf->importPage($i);
                        $pdf->UseTemplate($tplId);
                        if (($fileNumber < $filesTotal) || ($i != $pagesInFile)) 
                        {
                            $pdf->WriteHTML('<pagebreak />');
                        }
                      }
                    }
                    $fileNumber++;
                  }
                  $pdf->Output($Mpath);
                }
like image 177
krunal panchal Avatar answered Nov 03 '22 13:11

krunal panchal


This is an old question. I landed here after got stuck merging my PDFs as one and showing it in browser. Two answers above were tested by me and didn't work as expected. First page of the first file was shown correctly, first page of the second file jumped a blank page, and got truncted, i.e. only shown N-1 of N pages. The last page was missing. Here is a workaround I made after crawling into mpdf.php source code:

    function mergePDFFiles(Array $filenames, $outFile, $title='', $author = '', $subject = '') {
        $mpdf=new mPDF('c');
        $mpdf->SetTitle($title);
        $mpdf->SetAuthor($author);
        $mpdf->SetSubject($subject);
        if ($filenames) {
            $filesTotal = sizeof($filenames);
            $mpdf->SetImportUse();        
            for ($i = 0; $i<count($filenames);$i++) {
                $curFile = $filenames[$i];
                if (file_exists($curFile)){
                    $pageCount = $mpdf->SetSourceFile($curFile);
                    for ($p = 1; $p <= $pageCount; $p++) {
                        $tplId = $mpdf->ImportPage($p);
                        $wh = $mpdf->getTemplateSize($tplId);                
                        if (($p==1)){
                            $mpdf->state = 0;
                            $mpdf->UseTemplate ($tplId);
                        }
                        else {
                            $mpdf->state = 1;
                            $mpdf->AddPage($wh['w']>$wh['h']?'L':'P');
                            $mpdf->UseTemplate($tplId);    
                        }
                    }
                }                    
            }                
        }
        $mpdf->Output();
        unset($mpdf);
    }

$outFile is not used, because the resulting PDF is intended to be force to the browser.

like image 41
Buyut Joko Rivai Avatar answered Nov 03 '22 15:11

Buyut Joko Rivai


I Merge pdfs like this - {all pages in all files}:

$this = Class that extends mPDF class...

function mergePDFFiles(Array $filenames, $outFile)
{
    if ($filenames) {

        $filesTotal = sizeof($filenames);
        $fileNumber = 1;

        $this->SetImportUse(); // this line comment out if method doesnt exist

        if (!file_exists($outFile)) {
            $handle = fopen($outFile, 'w');
            fclose($handle);
        }

        foreach ($filenames as $fileName) {
            if (file_exists($fileName)) {
                $pagesInFile = $this->SetSourceFile($fileName);
                for ($i = 1; $i <= $pagesInFile; $i++) {
                    $tplId = $this->ImportPage($i); // in mPdf v8 should be 'importPage($i)'
                    $this->UseTemplate($tplId);
                    if (($fileNumber < $filesTotal) || ($i != $pagesInFile)) {
                        $this->WriteHTML('<pagebreak />');
                    }
                }
            }
            $fileNumber++;
        }

        $this->Output($outFile);

    }

}
like image 12
Vaci Avatar answered Nov 03 '22 13:11

Vaci