我想问一下如何将超过10万个pdf文件(每个pdf大约160 KB)合并到1个pdf文件中?
我已经阅读了本教程,该代码适用于少量pdf。但是,当我尝试10k pdf文件时,我收到此错误" java.lang.OutOfMemoryError:超出GC开销限制"
我已经尝试过使用-Xmx或-Xms,错误变成" java堆空间"。
我也在使用" 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();
谢谢
答案 0 :(得分:4)
合并大量PDF文档(或大型PDF)时,这是一个已知问题。
iText将尝试使生成的PDF尽可能小。它通过尝试重用对象来实现这一点。例如,如果您有一个多次出现的图像,而不是每次都嵌入该图像,它将嵌入一次,并简单地使用其他出现的参考。
这意味着iText必须将所有对象保留在内存中,因为无法事先知道对象是否会被重用。
通常有帮助的解决方案是批量分割流程。 不要将1000个文件合并为1,而是尝试成对合并1000个文件(产生500个文档),然后将每个文件成对合并(产生250个文档),依此类推。
这允许iText定期刷新缓冲区,这应该可以阻止内存开销导致VM崩溃。
答案 1 :(得分:0)
如果它不必是iText,您可以尝试使用支持合并文件的命令行应用程序。 PDFtk,QPDF和HexaPDF CLI(注意:我是HexaPDF的作者)是一些支持基本PDF文件合并的CLI工具。