PHP के साथ पीडीएफ फाइलों को मिलाएं [बंद]


83

मेरी अवधारणा है - एक वेबसाइट में 10 पीडीएफ फाइलें हैं। उपयोगकर्ता कुछ पीडीएफ फाइलों का चयन कर सकते हैं और फिर एकल पीडीएफ फाइल बनाने के लिए मर्ज का चयन कर सकते हैं जिसमें चयनित पृष्ठ हैं। मैं इसे php के साथ कैसे कर सकता हूं?


संबंधित प्रश्न (उत्तर दिया गया btw): stackoverflow.com/questions/2713701/…
फ्रेंक वेरोना

3
@Webnet वास्तव में, 64% ठीक है। मैं कहता हूँ 0 - 25% = विफल, लेकिन मुझे लगता है कि यह जहाँ व्यक्तिपरक हो जाता है
शॉन पैट्रिक फ्लोयड

क्या आप कमांड लाइन टूल का उपयोग कर सकते हैं?
पेका

क्या आप Zend फ्रेमवर्क का उपयोग कर सकते हैं? stackoverflow.com/questions/4254218/…
Pekka

मुझे "pdftk-112-1i386.rpm" फ़ाइल कहां मिल सकती है और इसे सर्वर पर कैसे स्थापित किया जाए?
इमरुल

जवाबों:


28

मैंने पहले भी ऐसा किया है। मेरे पास एक पीडीएफ था जो मैंने fpdf के साथ उत्पन्न किया था, और मुझे इसे पीडीएफ की एक चर राशि पर जोड़ने की आवश्यकता थी।

इसलिए मेरे पास पहले से ही एक fpdf ऑब्जेक्ट और पेज सेट अप था (http://www.fpdf.org/) और मैंने फ़ाइलों को आयात करने के लिए fpdi का उपयोग किया (http://www.setasign.de/products/pdf-php-solutions/ fpdi /) एफडीपीआई को पीडीएफ क्लास बढ़ाकर जोड़ा जाता है:

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

यह मूल रूप से प्रत्येक पीडीएफ को आपके अन्य पीडीएफ में डालने के लिए एक छवि बनाता है। यह आश्चर्यजनक रूप से अच्छी तरह से काम करता है जिसके लिए मुझे इसकी आवश्यकता थी।


मैं आपका कोड नहीं समझ सकता। क्या आप कृपया कुछ और विस्तार से बता सकते हैं? मुझे fpdf मेनुअल में "setSourceFile" और "importPage" फंक्शन्स नहीं मिले।
इमरूल

मैं वापस गया और अपने समाधान को थोड़ा और विस्तार से देखा। मुझे आशा है कि यह अधिक उपयोगी है। मैं पूरी तरह से आज सुबह fdpi के बारे में भूल गया जब मैंने यह लिखा था, इसका एक छोटा हिस्सा एक बहुत ही जटिल पीडीएफ जनरेटर मैंने लिखा था।
क्रिस्टा

7
@Christa खबरदार कि FPDI केवल कुछ पीडीएफ फाइलों को पार्स करेगी। मैं एक समस्या में चल रहा हूँ, जहाँ एफपीडीआई v 1.4 के ऊपर पीडीएफ फाइलों को पार्स नहीं करेगा और एफपीडीआई मुझे अपने पार्सर को> v1.4 ... यार ....
n0nag0n

क्या आपको नहीं लगता कि $ i = 0 और $ i = $ पेजकाउंट करना बेहतर है। यह मुझे लगता है कि पढ़ने के लिए बेहतर बनाता है। महान उदाहरण btw, वास्तव में मेरी मदद की
नेबुलसर

126

नीचे 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);

मुझे वह लिंक भूल गया जहां से मैंने इसे पाया था, लेकिन यह ठीक काम करता है।

नोट: आपके पास इस काम के लिए gs (linux और शायद Mac पर), या Ghostscript (खिड़कियों पर) स्थापित होना चाहिए।


4
यह मेरे लिए समस्याओं के बिना और बाहरी पुस्तकालयों को FPDI या अन्य के रूप में स्थापित किए बिना काम करता था।
मेमोचिपन

4
इस समाधान ने मेरे लिए सबसे अच्छा काम किया। मेरे सर्वर पर घोस्टस्क्रिप्ट को स्थापित करना बहुत आसान था। यह सिर्फ "yum install ghostscript" था। और आपकी स्क्रिप्ट पूरी तरह से काम करती है
थियो कोजेलिस

1
मुझे एक रिक्त पीडीऍफ़ पेज मिल रहा है :(
itsazzad

2
आपको Ghostscript स्थापित करने की आवश्यकता है, अन्यथा यह चुपचाप विफल रहता है।
पास्कल क्लेन

2
आपको यह समझाना चाहिए कि यह वास्तव में क्या करता है। यह वास्तव में कार्य करने के लिए वास्तव में एक php तरीका नहीं है, php में आप केवल डेटा तैयार करते हैं और फिर आप एक शेल स्क्रिप्ट निष्पादित करते हैं, जो वास्तविक कार्य करता है। इसके अलावा, आपको अपने उत्तर में शामिल होना चाहिए, कि gs (linux और शायद Mac पर), या Ghostscript (विंडोज़ पर) इसे काम करने के लिए स्थापित किया जाना चाहिए .. फिर भी मुझे यह समाधान काफी पसंद है, क्योंकि gs Ubuntu में डिफ़ॉल्ट रूप से शामिल है, मुझे लगता है , मुझे इसे स्थापित नहीं करना पड़ा।
वाल्गो एलियास

39

मैं github.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

3
यह मूल रूप से @ क्रिस्टा के उत्तर (FPDF + FDPI) का कार्यान्वयन है, जो बहुत अच्छा है :) धन्यवाद!
नहुएल

5
यह भी कुछ पीडीएफ पर कुछ प्रकार के संपीड़न के साथ काम नहीं करता है।
थियो कोजेलिस

3
DOMPDF के साथ इसका उपयोग करना और यह एक आकर्षण काम करता है धन्यवाद!
मैथ्यू

1
मुझे "FPDF त्रुटि: xref तालिका खोजने में असमर्थ है।" उसके लिए कोई समाधान?
समीरा 4ever

1
यह काम करता है लेकिन कुछ समय नीचे त्रुटि दिखाता है ... एफपीडीएफ त्रुटि: यह दस्तावेज़ (नमूनापद / चार.पीडी) संभवतः एक संपीड़न तकनीक का उपयोग करता है जो कि एफपीडीआई के साथ भेजे गए मुक्त पार्सर द्वारा समर्थित नहीं है।
निखिल

12
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=".$new." ".implode(" ", $files);
shell_exec($cmd);

चौहान के उत्तर का एक सरलीकृत संस्करण


यह मेरे लिए hostgator सेंटो समर्पित सर्वर पर ठीक काम किया है ताकि
भूतलेख

एक सही उत्तर के रूप में भी चिह्नित किया जाना चाहिए, क्योंकि यह बहुत आसान था। FPDF और FPDI के साथ संघर्ष कर रहे घंटे सही ढंग से लोड नहीं हो रहे हैं। तुमने मेरी जान बचाई। बस सर्वर पर "इमेजमैगिक" (डेबियन / ubuntu: apt इंस्टॉल इमेजमैगिक) स्थापित करने की आवश्यकता है और यह ठीक है। चियर्स!
फ्लोरियन डॉयेन

9

स्वीकृत उत्तर और यहां तक ​​कि FDPI मुखपृष्ठ दोनों बॉटेड या अधूरे उदाहरण देते हैं। यहाँ मेरा है जो काम करता है और लागू करना आसान है। जैसा कि अपेक्षित था कि इसे fpdf और fpdi पुस्तकालयों की आवश्यकता है:

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

Hi @billynoah मुझे यह पसंद है लेकिन यह परिदृश्य पर काम नहीं करता है और केवल 1 पृष्ठों को मर्ज करने के लिए लगता है।
गेराल्डो इसहाक

2
@GeraldoIsaaks - मैंने बाद में अपने स्वयं के आवेदन में बहु दस्तावेज़ों के लिए समर्थन जोड़ा। मैंने जवाब अपडेट कर दिया है। परिदृश्य मुद्दों के बारे में निश्चित नहीं है - मैं उस में नहीं चला हूं।
बिलिन्हा

एफपीडीआई के शुरुआती दिनों के बाद से उपलब्ध इस परीक्षा में क्या है ?
Jan Slabon

@ सेटिसाइन - मैंने कभी ऐसा नहीं देखा है लेकिन साझा करने के लिए धन्यवाद।
2

@billynoah एसओ में यहाँ स्पष्ट और अद्यतन सरल कोड उदाहरण के लिए धन्यवाद। यह मुझे शुरू कर दिया। मैं सेटैसाइन उदाहरण ( setasign.com/products/fpdi/demos/concatenate-fake , लिंक ऊपर से टिप्पणी में याद करना आसान है) से अधिक कोड का उपयोग करके समाप्त हुआ । AddPage कॉल के अंदर उनके तर्क ने मेरे विशेष रूप से संक्षिप्त पृष्ठों को बेहतर बनाया। संभवतया पोट्रेट / लैंडस्केप को भी बेहतर तरीके से संभालता है, हालांकि मैंने ऐसा नहीं किया। लेकिन मुझे खोज के साथ उदाहरण नहीं मिला और मुझे नहीं पता था कि जब तक मैंने आपका जवाब नहीं देखा था, तब तक मैं दिलचस्पी नहीं ले रहा था।
ऐनी गुन

5

मुझे अपने सॉफ़्टवेयर में ऐसी ही समस्या हुई है। हम कई पीडीएफ फाइलों को एक पीडीएफ फाइल में विलय करना चाहते हैं और इसे एक बाहरी सेवा में जमा करना चाहते हैं। हम FPDI समाधान का उपयोग कर रहे हैं जैसा कि क्रिस्टा के समाधान में दिखाया गया है ।

हालाँकि, इनपुट पीडीएफ का हम उपयोग कर रहे हैं, 1.7 से अधिक संस्करण में हो सकता है। हमने FPDI वाणिज्यिक ऐड-ऑन का मूल्यांकन करने का निर्णय लिया है। हालांकि, यह पता चला है कि हमारे कार्यालय कापियर द्वारा स्कैन किए गए कुछ दस्तावेजों में विकृत सूचकांक थे, जो वाणिज्यिक FPDI ऐड-ऑन को क्रैश कर गए थे। इसलिए हमने चौहान के उत्तर में घोस्टस्क्रिप्ट समाधान का उपयोग करने का निर्णय लिया है ।

लेकिन फिर हमें आउटपुट पीडीएफ गुणों में कुछ अजीब मेटाडेटा मिला।

अंत में हमने घोस्टस्क्रिप्ट द्वारा पीडीएफ को मर्ज और डाउनग्रेड करने के लिए दो समाधानों में शामिल होने का फैसला किया है, लेकिन मेटाडाटा एफपीडीआई द्वारा निर्धारित किया गया है। हम अभी तक नहीं जानते हैं कि यह कुछ उन्नत स्वरूपित pdfs के साथ कैसे काम करेगा, लेकिन स्कैन के लिए हम इसका उपयोग करते हैं यह ठीक काम करता है। यहाँ हमारी कक्षा अंश है:

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

बस उल्लेख करने के लिए, कि मैंने विंडोज एनवी पर समान कोड का उपयोग किया था। और प्रोग्राम फोल्डर डालना न भूलें, लेकिन पैरामीटर नहीं।$cmd = "\"C:\\Program Files\\gs\\gs9.20\\bin\\gswin64c.exe\" -q -dNOPAUSE -dBATCH -dCompatibilityLevel=1.4 -sDEVICE=pdfwrite -sOutputFile=[....your parameters...]" ;
Frédéric Klee

3

मैंने इसी तरह के मुद्दे की कोशिश की है और ठीक काम करता है, कोशिश करो। यह पीडीएफ के बीच विभिन्न झुकावों को संभाल सकता है।

    // 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
सेंटी

सुनिश्चित करें कि आपके पास FPDF ठीक से कॉन्फ़िगर किया गया है
केविन चुई

मेरे लिए पैरामीटर $ आकार ['चौड़ाई'] और $ आकार ['ऊँचाई'] $ आकार ['w'] और $ आकार ['h'] के
बजाय

0

मैंने FPDI पर एक अमूर्त परत बनाई (अन्य इंजनों को समायोजित कर सकता है)। मैंने इसे एक पुस्तकालय के आधार पर एक 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;
}

0

यह मेरे लिए विंडोज पर काम करता था

  1. PDFtk को https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/ से मुफ्त डाउनलोड करें
  2. ड्रॉप फ़ोल्डर (PDFtk) c की जड़ में:
  3. अपने 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);
    

एक PHP आवरण है जो इसे बहुत क्लीनर बनाता है। देखिए github.com/mikehaertl/php-pdftk
सीन द बीन

नोट: PdfTK RHEL 7 या Cent OS 7
Ray

मेरे लिए यह केवल इस तरह से काम करता था: $command = "cmd /c C:\\pdftk\\bin\\pdftk.exe {$file1} {$file2} cat output {$new}";अतिरिक्त बिल्ली उत्पादन को नोटिस करें । PDFtk उदाहरण
अधिकतम शक्ति power०००

-1

myokyawhtun के समाधान ने मेरे लिए सबसे अच्छा काम किया (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 पर भी यही बदलाव किया है

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.