Git Product home page Git Product logo

Comments (6)

JanSlabon avatar JanSlabon commented on July 26, 2024

The logic you use results in a very dirty PDF which seems to trigger some limitations in PDF viewers. In e.g. Chrome or Foxit you will notice the issue at 42 pages, in pdf.js is no issue at all.
The problem is that you re-import imported pages and you do this again for each page you "add". The internal structure will hold several duplicates of each page:
grafik
...the tree goes much deeper.

So to fix this just use a single run to import all pages instead of adding each after each:

$filenames = [];

for ($i = 1; $i <= 100; $i++) {
    $dompdf = new Dompdf();
    $dompdf->setPaper('letter', 'landscape');
    $dompdf->loadHtml("<h1>Page $i</h1>");
    $dompdf->render();

    $output = $dompdf->output();

    $filename = "$basePath/page-$i.pdf";
    file_put_contents($filename, $output);
    $filenames[] = $filename;
}

$pdf = new Fpdi();

foreach($filenames AS $file) {
    $pageCount = $pdf->setSourceFile($file);

    for ($page = 1; $page <= $pageCount; $page++) {
        $pageId = $pdf->importPage($page);
        $templateSize = $pdf->getTemplatesize($pageId);
        $pdf->AddPage($templateSize['orientation'], $templateSize);
        $pdf->useImportedPage($pageId);
    }
}

$output = $pdf->Output('S');

$filename = "$basePath/merged.pdf";
file_put_contents($filename, $output);

You should understand that you cannot edit a PDF with FPDI but you import the pages of an existing one and place them onto new pages. If you do this recursively the internal structure will also grow appropriately and it looks like some PDF viewers have some limit in view to such structures. This may be an issue of a nesting level of graphic states - which was documented in PDF 1.7 but was removed in 2.0. Maybe it's simply a security check as such recursion looks sus.

Generally try to avoid importing of PDFs which were imported earlier but start with the original documents.
If you really want to append a PDF to another on a low level feel free to check out our SetaPDF-Merger component. It can be initiated with an existing document instance: https://manuals.setasign.com/setapdf-merger-manual/the-main-class/#index-2

from fpdi.

davidhirtz avatar davidhirtz commented on July 26, 2024

Hi @JanSlabon,

Thank you very much for this insightful reply. The code provided was just a test snippet, in the real application we can of course create the single PDFs before merging them. But I would still need to combine 100's of PDFs into a single document at some point. If I use your example code I quickly run into a "Failed to open stream: Too many open files" exception. Is there any way to close the files after adding them?

I will also take a look at the SetaPDF-Merger component, unfortunately with this project I'm pretty tight on paid solutions...

Thank you again!

from fpdi.

JanSlabon avatar JanSlabon commented on July 26, 2024

[...]"Failed to open stream: Too many open files"[...]

Long time not seen this error. Especially at only 100 files. You may increase this on OS level or split this at the max number (if you do this several times, you end in the same situation as you initially reported). But again the SetaPDF-Merger component got you covered: https://manuals.setasign.com/setapdf-merger-manual/performance-optimizations/#index-2

from fpdi.

davidhirtz avatar davidhirtz commented on July 26, 2024

Haha thanks, yeah the error did not happen around 100 files – more like 800 PDFs in. If there is no way to do this with an open source solution, I'll try to get the funds for the commercial licence. Thank you!

from fpdi.

JanSlabon avatar JanSlabon commented on July 26, 2024

You can try to hold the files in memory: https://manuals.setasign.com/fpdi-manual/v2/the-fpdi-class/#index-4
But internally FPDI makes use of streams - I'm not sure if this counts as file-handles, too.
If not it will, for sure, increase the memory usage which may trigger the next limitation (memory_limit).

Also for this the SetaPDF-Merger got you covered as you can work with an intermediate result to free memory: https://manuals.setasign.com/setapdf-merger-manual/performance-optimizations/#index-4

from fpdi.

davidhirtz avatar davidhirtz commented on July 26, 2024

Thank you again for your help. I was actually able to solve this with a simple shell_exec command and Ghostscript, this Gist was very helpful. The command only needs a few seconds for merging 800+ PDFs.

Closing this ...

from fpdi.

Related Issues (20)

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.