PHP - 如何使用 mPDF 合并 PDF

Posted

技术标签:

【中文标题】PHP - 如何使用 mPDF 合并 PDF【英文标题】:PHP - How to use mPDF to merge PDFs 【发布时间】:2014-12-12 09:42:08 【问题描述】:

首先我会说我可以使用 mPDF 很好地生成 PDF,但是对于我的生活,我无法将现有的 PDF 与它刚刚生成的 PDF 合并。

我需要弄清楚的是如何将现有的 PDF 附加/添加到新生成的 PDF 中。我已经尝试使用 mPDF 方法来导入页面,但我能得到的只是一个错误,例如:

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

上面的消息是模棱两可的,不清楚为什么它不能打开文件...... 这是我用来尝试合并 PDF 的代码:

 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 将是显示给用户的文件名。 $url 是我们在 PDF 生成期间写入文件的 HTML。 $technical_drawing 是我们想要与生成的 PDF 附加/合并的 PDF 的相对路径。

我知道我可以使用 ghostscript 之类的东西,但我在客户端的服务器上没有这种类型的访问权限。

如果有人使用 mPDF 找到解决方案,或者我是 S.O.L.,请告诉我。并且需要找到另一个库来进行 PDF 合并。我真的在寻找解决方案或建议,而不仅仅是指向另一个库的链接。我已经用尽了可以在 Google 或 mPDF 文档中找到的描述我遇到的错误的内容。

编辑:将 mPDF 错误从 http://example.com/pdf/example.pdf 更改为“/downloads/test.pdf”。

EDIT_2:代码已修复为采用相对路径。

这是最终的工作代码。如果有人知道如何指定将 HTML 写入 PDF 文档的顺序,将页面作为最后一页导入(自定义页面大小与 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;

【问题讨论】:

网址http://example.com/pdf/example.pdf来自哪里? 你应该提供本地文件路径而不是 url @zerkms - 抱歉,澄清一下,这不是 example.com。我的网址设置为本地路径,例如“/downloads/test.pdf”。 具体来说,$technical_drawing = '/downloads/test.pdf' 那么,有/downloads/test.pdf 路径吗?如果您打开终端并运行ls /downloads/test.pdf,您会看到什么? 【参考方案1】:

我像这样合并 pdf - 所有文件中的所有页面:

$this = 扩展 mPDF 类的类...

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

    


【讨论】:

这给了我一个空白的pdf,你不需要将模板添加为页面吗? 对我帮助很大。谢谢【参考方案2】:

此代码适用于 mpdf 8.0.7 和 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);
                

【讨论】:

【参考方案3】:

这是一个老问题。在将我的 PDF 合并为一个并在浏览器中显示之后,我来到了这里。上面的两个答案经过我的测试,并没有按预期工作。第一个文件的第一页显示正确,第二个文件的第一页跳转一个空白页,并被截断,即仅显示 N-1 页中的 N-1 页。最后一页不见了。 这是我爬入mpdf.php源代码后做的一个变通方法:

    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 未使用,因为生成的 PDF 旨在强制浏览器。

【讨论】:

【参考方案4】:
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');
    

【讨论】:

以上是关于PHP - 如何使用 mPDF 合并 PDF的主要内容,如果未能解决你的问题,请参考以下文章

如何使用php合并两个pdf文件

MPDF,将包含几页的 PDF 与当前页合并

如何使用 mpdf 发送 pdf 电子邮件?

如何通过mPDF将信息导出到一个单独页面的pdf文件中

mPDF 以 PDF 为中心进行打印

创建更大的 pdf 时,mpdf 内存太低