用PHP合并PDF文件
我的概念是 – 网站上有10个pdf文件。 用户可以select一些PDF文件,并select合并,以创build一个包含选定页面的单个PDF文件。 我怎样才能做到这一点与PHP?
我以前做过。 我有一个pdf,我用fpdf生成,我需要添加一个可变数量的PDF到它。
所以我已经有一个fpdf对象和页面设置(http://www.fpdf.org/)我用fpdi来导入文件(http://www.setasign.de/products/pdf-php-solutions/ fpdi /)通过扩展PDF类来添加FDPI:
class PDF extends FPDI { } $pdffile = "Filename.pdf"; $pagecount = $pdf->setSourceFile($pdffile); for($i=0; $i<$pagecount; $i++){ $pdf->AddPage(); $tplidx = $pdf->importPage($i+1, '/MediaBox'); $pdf->useTemplate($tplidx, 10, 10, 200); }
这基本上使每个PDF成为一个图像,把你的其他pdf。 它工作得非常好,我所需要的。
下面是php PDF合并命令。
$fileArray= array("name1.pdf","name2.pdf","name3.pdf","name4.pdf"); $datadir = "save_path/"; $outputName = $datadir."merged.pdf"; $cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=$outputName "; //Add each pdf file to the end of the command foreach($fileArray as $file) { $cmd .= $file." "; } $result = shell_exec($cmd);
我忘了从哪里find它的链接,但它工作正常。
我build议从pdfmerger.codeplex.com PDFMerger ,如此简单::
include 'PDFMerger.php'; $pdf = new PDFMerger; $pdf->addPDF('samplepdfs/one.pdf', '1, 3, 4') ->addPDF('samplepdfs/two.pdf', '1-2') ->addPDF('samplepdfs/three.pdf', 'all') ->merge('file', 'samplepdfs/TEST2.pdf'); // REPLACE 'file' WITH 'browser', 'download', 'string', or 'file' for output options
在PDFMerger中使用的代码在PHP5版本中已被弃用。 我分叉和固定的代码与PHP 5工作。你可以抓住我的github帐户https://github.com/myokyawhtun/PDFMerger
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=".$new." ".implode(" ", $files); shell_exec($cmd);
Chauhan的答案的简化版本
不太清楚为什么接受的答案,甚至是FDPI主页似乎都给出了拙劣或不完整的例子。 这是我的工作,很容易实现。 正如所料,它需要fpdf和fpdi库:
- FPDF: http ://www.fpdf.org/en/download.php
- FPDI: https ://www.setasign.com/products/fpdi/downloads
require('fpdf.php'); require('fpdi.php'); $files = ['doc1.pdf', 'doc2.pdf', 'doc3.pdf']; $pdf = new FPDI(); // iterate over array of files and merge foreach ($files as $file) { $pageCount = $pdf->setSourceFile($file); for ($i = 0; $i < $pageCount; $i++) { $tpl = $pdf->importPage($i + 1, '/MediaBox'); $pdf->addPage(); $pdf->useTemplate($tpl); } } // output the pdf as a file (http://www.fpdf.org/en/doc/output.htm) $pdf->Output('F','merged.pdf');
我的软件有类似的问题。 我们希望将几个PDF文件合并成一个PDF文件,并将其提交给外部服务。 我们一直在使用FPDA解决scheme,如Christa解决scheme所示。
但是,我们使用的inputPDF版本可能会高于1.7。 我们决定评估FPDI商业插件。 然而,事实certificate,我们的办公室复印机扫描的一些文件索引格式不正确,导致商业FPDI附件崩溃。 所以我们决定像Chauhan的答案一样使用Ghostscript解决scheme。
但是,我们在输出PDF属性中获得了一些奇怪的元数据。
最后,我们决定join两个解决scheme来获取由Ghostscript合并和降级的PDF,但元数据由FPDI设置。 我们还不知道如何使用一些高级格式化的pdf,但对于我们使用它的扫描工作得很好。 这是我们的课堂摘录:
class MergedPDF extends \FPDI { private $documentsPaths = array(); public function Render() { $outputFileName = tempnam(sys_get_temp_dir(), 'merged'); // merge files and save resulting file as PDF version 1.4 for FPDI compatibility $cmd = "/usr/bin/gs -q -dNOPAUSE -dBATCH -dCompatibilityLevel=1.4 -sDEVICE=pdfwrite -sOutputFile=$outputFileName"; foreach ($this->getDocumentsPaths() as $pdfpath) { $cmd .= " $pdfpath "; } $result = shell_exec($cmd); $this->SetCreator('Your Software Name'); $this->setPrintHeader(false); $numPages = $this->setSourceFile($outputFileName); for ($i = 1; $i <= $numPages; $i++) { $tplIdx = $this->importPage($i); $this->AddPage(); $this->useTemplate($tplIdx); } unlink($outputFileName); $content = $this->Output(null, 'S'); return $content; } public function getDocumentsPaths() { return $this->documentsPaths; } public function setDocumentsPaths($documentsPaths) { $this->documentsPaths = $documentsPaths; } public function addDocumentPath($documentPath) { $this->documentsPaths[] = $documentPath; } }
这个类的用法如下:
$pdf = new MergedPDF(); $pdf->setTitle($pdfTitle); $pdf->addDocumentPath($absolutePath1); $pdf->addDocumentPath($absolutePath2); $pdf->addDocumentPath($absolutePath3); $tempFileName = tempnam(sys_get_temp_dir(), 'merged'); $content = $pdf->Render(); file_put_contents($tempFileName, $content);
我曾尝试类似的问题,并正常工作,尝试一下。 它可以处理PDF之间的不同方向。
// array to hold list of PDF files to be merged $files = array("a.pdf", "b.pdf", "c.pdf"); $pageCount = 0; // initiate FPDI $pdf = new FPDI(); // iterate through the files foreach ($files AS $file) { // get the page count $pageCount = $pdf->setSourceFile($file); // 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, 'Generated by FPDI'); } }
这在Windows上适用于我
- 从https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/免费下载PDFtk
- 将文件夹(PDFtk)放入c:
-
将以下内容添加到您的php代码中,其中$ file1是第一个PDF文件的位置和名称,$ file2是第二个文件的位置和名称,$ newfile是目标文件的位置和名称
$file1 = ' c:\\\www\\\folder1\\\folder2\\\file1.pdf'; $file2 = ' c:\\\www\\\folder1\\\folder2\\\file2.pdf'; $file3 = ' c:\\\www\\\folder1\\\folder2\\\file3.pdf'; $command = 'cmd /c C:\\\pdftk\\\bin\\\pdftk.exe '.$file1.$file2.$newfile; $result = exec($command);
myokyawhtun的解决scheme最适合我(使用PHP 5.4)
你仍然会得到一个错误 – 我解决了使用以下内容:
fpdf_tpl.php的第269行 – 将函数参数更改为:
function Image($file, $x=null, $y=null, $w=0, $h=0, $type='', $link='',$align='', $resize=false, $dpi=300, $palign='', $ismask=false, $imgmask=false, $border=0) {
我也在fpdf.php的第898行做了同样的改变
我在FPDI上创build了一个抽象层(可能容纳其他引擎)。 我把它作为一个Symfony2包发布,依赖于一个库和库本身。
捆绑
图书馆
用法:
public function handlePdfChanges(Document $document, array $formRawData) { $oldPath = $document->getUploadRootDir($this->kernel) . $document->getOldPath(); $newTmpPath = $document->getFile()->getRealPath(); switch ($formRawData['insertOptions']['insertPosition']) { case PdfInsertType::POSITION_BEGINNING: // prepend $newPdf = $this->pdfManager->insert($oldPath, $newTmpPath); break; case PdfInsertType::POSITION_END: // Append $newPdf = $this->pdfManager->append($oldPath, $newTmpPath); break; case PdfInsertType::POSITION_PAGE: // insert at page n: PdfA={p1; p2; p3}, PdfB={pA; pB; pC} // insert(PdfA, PdfB, 2) will render {p1; pA; pB; pC; p2; p3} $newPdf = $this->pdfManager->insert( $oldPath, $newTmpPath, $formRawData['insertOptions']['pageNumber'] ); break; case PdfInsertType::POSITION_REPLACE: // does nothing. overrides old file. return; break; } $pageCount = $newPdf->getPageCount(); $newPdf->renderFile($mergedPdfPath = "$newTmpPath.merged"); $document->setFile(new File($mergedPdfPath, true)); return $pageCount; }
显示/生成什么我需要使2个页面的source.pdf。 “pdf / Source.pdf”是2页,但是仅显示/生成一个页面。
这是原来的代码…
require_once('pdf/fpdf/fpdf.php'); require_once('pdf/fpdi/fpdi.php'); $x34 = new FPDI(); $x34->AddPage(); $x34->setSourceFile("pdf/Source.pdf"); $x35 = $x34->importPage(1); $x34->useTemplate($x35, 0, 0, 200); $x34->SetFont('Arial'); $x34->SetFontSize(10.0);