PHP - How to use mPDF to merge PDFs

2019-04-07 02:39发布

问题:

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;

回答1:

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();

        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);
                    $this->UseTemplate($tplId);
                    if (($fileNumber < $filesTotal) || ($i != $pagesInFile)) {
                        $this->WriteHTML('<pagebreak />');
                    }
                }
            }
            $fileNumber++;
        }

        $this->Output($outFile);

    }

}


回答2:

function mergePDFFiles(Array $filenames, $outFile) {
    $mpdf = new mPDF();
    if ($filenames) {
        //  print_r($filenames); die;
        $filesTotal = sizeof($filenames);
        $fileNumber = 1;
        $mpdf->SetImportUse();
        if (!file_exists($outFile)) {
            $handle = fopen($outFile, 'w');
            fclose($handle);
        }
        foreach ($filenames as $fileName) {
            if (file_exists($fileName)) {
                $pagesInFile = $mpdf->SetSourceFile($fileName);
                //print_r($fileName); die;
                for ($i = 1; $i <= $pagesInFile; $i++) {
                    $tplId = $mpdf->ImportPage($i);
                    $mpdf->UseTemplate($tplId);
                    if (($fileNumber < $filesTotal) || ($i != $pagesInFile)) {
                        $mpdf->WriteHTML('<pagebreak />');
                    }
                }
            }
            $fileNumber++;
        }
        $mpdf->Output($outFile, 'D');
    }
}


回答3:

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.