Benim konseptim - bir web sitesinde 10 pdf dosyası var. Kullanıcı bazı pdf dosyalarını seçebilir ve ardından seçilen sayfaları içeren tek bir pdf dosyası oluşturmak için birleştirmeyi seçebilir. Bunu php ile nasıl yapabilirim?
Benim konseptim - bir web sitesinde 10 pdf dosyası var. Kullanıcı bazı pdf dosyalarını seçebilir ve ardından seçilen sayfaları içeren tek bir pdf dosyası oluşturmak için birleştirmeyi seçebilir. Bunu php ile nasıl yapabilirim?
Yanıtlar:
Bunu daha önce yaptım. Fpdf ile oluşturduğum bir pdf'im vardı ve ona değişken miktarda PDF eklemem gerekiyordu.
Bu yüzden zaten bir fpdf nesnem ve sayfa kurulumum vardı (http://www.fpdf.org/) Ve dosyaları içe aktarmak için fpdi kullandım (http://www.setasign.de/products/pdf-php-solutions/ fpdi /) FDPI, PDF sınıfı genişletilerek eklenir:
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);
}
Bu, temelde her pdf'yi diğer pdf'nize koymak için bir görüntü haline getirir. İhtiyacım olan şey için inanılmaz derecede iyi çalıştı.
Aşağıda php PDF birleştirme komutu verilmiştir.
$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);
Bağlantıyı bulduğum yerden unuttum ama iyi çalışıyor.
Not: Bunun çalışması için gs (Linux'ta ve muhtemelen Mac'te) veya Ghostscript (Windows'ta) kurulu olmalıdır.
i önermek PDFMerger dan github.com kadar kolay olduğu gibi, ::
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
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=".$new." ".implode(" ", $files);
shell_exec($cmd);
Chauhan'ın cevabının basitleştirilmiş bir versiyonu
Hem kabul edilen cevap hem de FDPI ana sayfası başarısız veya eksik örnekler veriyor gibi görünüyor. İşte çalışan ve uygulaması kolay olan benim. Beklendiği gibi, fpdf ve fpdi kitaplıklarını gerektirir:
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');
Yazılımımda da benzer bir sorun yaşadım. Birkaç PDF dosyasını tek bir PDF dosyasında birleştirmek ve bir dış hizmete göndermek istedik. Gösterildiği gibi FPDI çözümü kullanıyorum Christa 'ın çözümü.
Ancak, kullandığımız girdi PDF'leri 1.7'den yüksek sürümde olabilir. FPDI ticari eklentisini değerlendirmeye karar verdik. Ancak, ofis fotokopi makinemiz tarafından taranan bazı belgelerin, ticari FPDI eklentisini çökerten hatalı biçimlendirilmiş dizinlere sahip olduğu ortaya çıktı. Bu yüzden Chauhan'ın cevabında olduğu gibi Ghostscript çözümünü kullanmaya karar verdik .
Ancak çıktı PDF özelliklerinde bazı garip meta veriler elde ettik.
Sonunda PDF'lerin Ghostscript tarafından birleştirilip indirgenmesi için iki çözümü birleştirmeye karar verdik, ancak meta veriler FPDI tarafından belirleniyor. Bazı gelişmiş biçimlendirilmiş pdf'lerle nasıl çalışacağını henüz bilmiyoruz, ancak kullandığımız taramalar için gayet iyi çalışıyor. İşte sınıftan alıntımız:
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;
}
}
Bu sınıfın kullanımı aşağıdaki gibidir:
$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);
$cmd = "\"C:\\Program Files\\gs\\gs9.20\\bin\\gswin64c.exe\" -q -dNOPAUSE -dBATCH -dCompatibilityLevel=1.4 -sDEVICE=pdfwrite -sOutputFile=[....your parameters...]" ;
Benzer sorunu denedim ve iyi çalışıyor, deneyin. PDF'ler arasındaki farklı yönlendirmeleri işleyebilir.
// 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');
}
}
Undefined index: w
FPDI üzerinde bir soyutlama katmanı oluşturdum (diğer motorları da barındırabilir). Kitaplığa bağlı olarak Symfony2 paketi ve kitaplığın kendisi olarak yayınladım.
kullanım:
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;
}
Bu benim için Windows'ta çalıştı
Aşağıdakileri php kodunuza ekleyin; burada $ file1, ilk PDF dosyasının konumu ve adı, $ file2, ikincinin konumu ve adı ve $ newfile, hedef dosyanın konumu ve adıdır
$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);
$command = "cmd /c C:\\pdftk\\bin\\pdftk.exe {$file1} {$file2} cat output {$new}";Ek cat çıktısına dikkat edin . PDFtk örneklerine
myokyawhtun'un çözümü benim için en iyi şekilde çalıştı (PHP 5.4 kullanarak)
Yine de bir hata alacaksınız - aşağıdakileri kullanarak çözdüm:
Fpdf_tpl.php'nin 269. satırı - işlev parametrelerini şu şekilde değiştirdi:
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) {
Aynı değişikliği fpdf.php'nin 898. satırında da yaptım.