Scalanie plików PDF z PHP

Moja koncepcja jest taka - na stronie jest 10 plików pdf. użytkownik może wybrać niektóre pliki pdf i wybrać merge, aby utworzyć pojedynczy plik pdf, który zawiera wybrane strony. Jak mogę to zrobić z php?

 58
Author: Imrul.H, 2011-01-25

11 answers

Robiłam to już wcześniej. Miałem plik pdf, który wygenerowałem za pomocą fpdf i musiałem dodać do niego zmienną ilość plików PDF.

Więc miałem już ustawiony obiekt fpdf i stronę (http://www.fpdf.org/) A do importowania plików użyłem fpdi (http://www.setasign.de/products/pdf-php-solutions/fpdi/) FDPI jest dodawane przez rozszerzenie klasy PDF:

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

To w zasadzie sprawia, że każdy plik pdf jest obrazem, który można umieścić w innym pliku pdf. Działał niesamowicie dobrze do tego, do czego go potrzebowałem.

 20
Author: Christa,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-01-25 19:00:17

Poniżej znajduje się polecenie PHP PDF merge.

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

Zapomniałem linku skąd go znalazłem, ale działa dobrze.

 88
Author: Sanjeev Chauhan,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2011-06-09 04:45:10

Proponuję PDFMerger z pdfmerger.codeplex.com, so easy like::

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
 28
Author: AgelessEssence,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-01-30 20:44:55
$cmd = "gs -q -dNOPAUSE -dBATCH -sDEVICE=pdfwrite -sOutputFile=".$new." ".implode(" ", $files);
shell_exec($cmd);

Uproszczona wersja odpowiedzi Chauhana

 9
Author: Svetoslav Genov,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-04-24 20:54:11

Kody używane w PDFMerger są przestarzałe w wersji PHP5. Rozwidlałem i poprawiłem kody do pracy z PHP 5. Możesz pobrać NA MOJE KONTO github https://github.com/myokyawhtun/PDFMerger

 8
Author: myokyawhtun,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-05-20 06:20:05

Miałem podobny problem w moim oprogramowaniu. Chcieliśmy połączyć kilka plików PDF w jeden plik PDF i przesłać go do zewnętrznej usługi. Używamy rozwiązania FPDI, jak pokazano w rozwiązaniu Christa .

Jednak wejściowe pliki PDF, których używamy, mogą być w wersji wyższej niż 1.7. Zdecydowaliśmy się na ocenę komercyjnego dodatku FPDI. Okazało się jednak, że część dokumentów zeskanowanych przez naszą kopiarkę biurową miała zniekształcone indeksy, co załamało komercyjny dodatek FPDI. Postanowiliśmy więc użyć rozwiązania Ghostscript jak w odpowiedzi Chauhana .

Ale potem dostaliśmy dziwne metadane w wyjściowych właściwościach PDF.

W końcu zdecydowaliśmy się połączyć dwa rozwiązania, aby uzyskać połączenie PDF i obniżoną ocenę przez Ghostscript, ale metadane są ustawiane przez FPDI. Nie wiemy jeszcze, Jak to będzie działać z niektórymi zaawansowanymi sformatowanymi plikami PDF,ale dla skanów używamy go dobrze. Oto fragment naszej klasy:

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

Użycie do tej klasy należy:

$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);
 4
Author: Artur Karczmarczyk,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-02-16 12:01:23

Nie do końca wiem, dlaczego zarówno akceptowana odpowiedź, jak i nawet Strona główna fdpi wydają się dawać nieudane lub niekompletne przykłady. Oto mój, który działa i jest łatwy do wdrożenia. Zgodnie z oczekiwaniami wymaga bibliotek fpdf i 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');
 4
Author: billynoah,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2016-09-22 12:36:55

Próbowałem podobny problem i działa dobrze, spróbuj. Może obsługiwać różne orientacje między plikami 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');
        }
    }
 2
Author: Kevin Chui,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-04-10 02:30:02

To działało u mnie na Windows

  1. Pobierz PDFtk za darmo z https://www.pdflabs.com/tools/pdftk-the-pdf-toolkit/
  2. upuść folder (PDFtk) do katalogu głównego c:
  3. Dodaj następujący kod php, gdzie $file1 to lokalizacja i nazwa pierwszego pliku PDF, $file2 to lokalizacja i nazwa drugiego, a $newfile to lokalizacja i nazwa pliku docelowego

    $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);
    
 1
Author: Stewart Kirkpatrick,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2015-09-03 12:12:29

Rozwiązanie Myokyawhtun zadziałało najlepiej dla mnie (używając PHP 5.4)

Nadal pojawi się błąd - rozwiązałem za pomocą następującego:

Linia 269 fpdf_tpl.php-zmieniono parametry funkcji na:

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

Dokonałem również tej samej zmiany na linii 898 fpdf.php

 0
Author: Scott,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-11-22 17:56:13

Stworzyłem warstwę abstrakcji nad FPDI (może pomieścić inne silniki). Opublikowałem go jako pakiet Symfony2 w zależności od biblioteki i jako samą bibliotekę.

Pakiet

Biblioteka

Użycie:

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
Author: juanmf,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2014-07-25 23:28:54