如何合并多个pdf

How to merge many pdfs

我想问一下如何将超过 100k 的 pdf 文件(每个 pdf 文件大约 160 KB)合并为 1 个 pdf 文件?

Tutorial

我已经阅读了本教程,该代码适用于少数 pdf。但是当我尝试 10k pdf 文件时,我得到这个错误 "java.lang.OutOfMemoryError: GC overhead limit exceeded"

我已经尝试使用 -Xmx 或 -Xms,错误变为 "java heap space"。

我也在用 "pdf.flushCopiedObjects(firstSourcePdf);" 没用。还是我使用不当?

File file = new File(pathName);
        File[] listFile = file.listFiles();
        if (listFile == null) {
            throw new Exception("File not Found at " + pathName);
        }
        Arrays.sort(listFile, 0, listFile.length - 1);

        PdfADocument pdf = new PdfADocument(new PdfWriter(dest),
            PdfAConformanceLevel.PDF_A_1A,
            new PdfOutputIntent("Custom", "", "http://www.color.org",
                "sRGB IEC61966-2.1", null));

        //Setting some required parameters
        pdf.setTagged();
        pdf.getCatalog().setLang(new PdfString("en-US"));
        pdf.getCatalog().setViewerPreferences(
            new PdfViewerPreferences().setDisplayDocTitle(true));
        PdfDocumentInfo info = pdf.getDocumentInfo();
        info.setTitle("iText7 PDF/A-1a example");

        //Create PdfMerger instance
        PdfMerger merger = new PdfMerger(pdf);
        //Add pages from the first document

        for (File filePdf : listFile) {
            System.out.println("filePdf = " +filePdf.getName());
            PdfDocument firstSourcePdf = new PdfDocument(new PdfReader(filePdf));
            merger.merge(firstSourcePdf, 1, firstSourcePdf.getNumberOfPages());
            pdf.flushCopiedObjects(firstSourcePdf);
            firstSourcePdf.close();
        }

        pdf.close();

谢谢

这是合并大量 PDF 文档(或大型 PDF)时的已知问题。

iText 将尝试使生成的 PDF 尽可能小。它通过尝试重用对象来做到这一点。例如,如果您有一个多次出现的图像,它不会每次都嵌入该图像,而是会嵌入一次并简单地为其他出现的图像使用一个参考。

这意味着 iText 必须将所有对象保存在内存中,因为无法事先知道对象是否会被重用。

一个通常有用的解决方案是分批处理。 不要将 1000 个文件合并为 1 个文件,而是尝试将 1000 个文件成对合并(产生 500 个文档),然后将每个文件成对合并(产生 250 个文档),依此类推。

这允许 iText 定期刷新缓冲区,这应该会阻止内存开销导致 VM 崩溃。

如果不必是iText,您可以尝试使用支持文件合并的命令行应用程序。 PDFtk, QPDF and HexaPDF CLI(注意:我是 HexaPDF 的作者)是一些支持基本 PDF 文件合并的 CLI 工具。