Java 使用PDFBox复制pdf是否可以像使用iText一样小?
我正在阅读一份PDF文件,并输出一份包含多份原始PDF副本的PDF文件。我通过对和做同样的事情来进行测试。如果我单独复制每个页面,iText将创建更小的输出 问题是:在PDFBox中是否有其他方法可以实现这一点,从而产生更小的输出PDF 对于一个示例输入文件,使用两种工具生成两个输出副本: 原始PDF大小:30K PDFBox v 1.7.1生成的PDF:84K iText v 5.3.4生成的PDF:35K PDFBox的Java代码很抱歉给您造成错误处理。注意它是如何反复读取输入并将其作为一个整体复制的:Java 使用PDFBox复制pdf是否可以像使用iText一样小?,java,itext,pdfbox,Java,Itext,Pdfbox,我正在阅读一份PDF文件,并输出一份包含多份原始PDF副本的PDF文件。我通过对和做同样的事情来进行测试。如果我单独复制每个页面,iText将创建更小的输出 问题是:在PDFBox中是否有其他方法可以实现这一点,从而产生更小的输出PDF 对于一个示例输入文件,使用两种工具生成两个输出副本: 原始PDF大小:30K PDFBox v 1.7.1生成的PDF:84K iText v 5.3.4生成的PDF:35K PDFBox的Java代码很抱歉给您造成错误处理。注意它是如何反复读取输入并将其作为一
PDFMergerUtility merger = new PDFMergerUtility();
PDDocument workplace = null;
try {
for (int cnt = 0; cnt < COPIES; ++cnt) {
PDDocument document = null;
InputStream stream = null;
try {
stream = new FileInputStream(new File(sourceFileName));
document = PDDocument.load(stream);
if (workplace == null) {
workplace = document;
} else {
merger.appendDocument(workplace, document);
}
} finally {
if (document != null && document != workplace) {
document.close();
}
if (stream != null) {
stream.close();
}
}
}
OutputStream out = null;
try {
out = new FileOutputStream(new File(destinationFileName));
workplace.save(out);
} finally {
if (out != null) {
out.close();
}
}
} catch (COSVisitorException e1) {
e1.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
} finally {
if (workplace != null) {
try {
workplace.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
使用以下解决方案,我能够创建一个包含许多重复页面的PDF文件,并且对存储的影响最小
PDDocument samplePdf = null;
try {
samplePdf = PDDocument.load(PDF_PATH);
PDPage page = (PDPage) samplePdf.getDocumentCatalog().getAllPages().get(0);
for(int i = 0; i < COPIES; i++) {
samplePdf.importPage(page);
}
samplePdf.save(SAVE_PATH); //$NON-NLS-1$
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
在我的第一次尝试中,我使用了samplePdf.addPagepage,但它没有按预期工作。所以很明显,add和import函数之间存在差异。我必须检查源代码或文档以了解原因。无论如何,这将帮助您设计一个解决方案来满足您对PDFBox的需求。使用以下解决方案,我能够创建一个包含许多重复页面的PDF文件,并且对存储的影响最小
PDDocument samplePdf = null;
try {
samplePdf = PDDocument.load(PDF_PATH);
PDPage page = (PDPage) samplePdf.getDocumentCatalog().getAllPages().get(0);
for(int i = 0; i < COPIES; i++) {
samplePdf.importPage(page);
}
samplePdf.save(SAVE_PATH); //$NON-NLS-1$
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}
在我的第一次尝试中,我使用了samplePdf.addPagepage,但它没有按预期工作。所以很明显,add和import函数之间存在差异。我必须检查源代码或文档以了解原因。无论如何,这将有助于你设计一个解决方案来满足你对PDFBox的需求。IMHO这是一个关于经济学的问题,而不是一个纯粹的技术问题。您有一个使用iText的工作解决方案,但您希望使用PdfBox。这种选择是有代价的。我想你更喜欢PdfBox是因为ASL。然而,由于没有人为PdfBox付费,所以您不应该期望该库速度快、功能丰富、完整,。。。我在2009年将iText许可证从MPL/AGPL更改为AGPL,因为我需要开始创收以确保库的进一步开发。如果没有这笔收入,iText将慢慢消亡。@BrunoLowagie我理解你的意思,但由于我不是这两个图书馆的专家,我找到了一个可行的解决方案。也许还有另一种使用PDFBox的解决方案,可以创建更小的PDF文件。也许不是。也许iText在这方面更适合我的需要。我只是想从这两种工具的专家那里得到一些帮助。这就提出了一个问题,因为您是iText的专家,我是否有在iText中创建重复页面的最佳解决方案?PdfSmartCopy会在内存中保留某些对象的散列,例如早期版本的iText中的流和最新版本中的字体字典。每当重用对象时,我们都会添加对原始对象的引用,而不是像使用PdfCopy而不是PdfSmartCopy那样复制它。Acrobat甚至做得更好:Acrobat可以将同一字体的不同子集合并成一个更大的子集。我们还不支持这一点,因为它涉及重写整个内容流,而不是琐碎的内容+需要更多的CPU/内存。这与其说是一个纯粹的技术问题,不如说是一个经济学问题。您有一个使用iText的工作解决方案,但您希望使用PdfBox。这种选择是有代价的。我想你更喜欢PdfBox是因为ASL。然而,由于没有人为PdfBox付费,所以您不应该期望该库速度快、功能丰富、完整,。。。我在2009年将iText许可证从MPL/AGPL更改为AGPL,因为我需要开始创收以确保库的进一步开发。如果没有这笔收入,iText将慢慢消亡。@BrunoLowagie我理解你的意思,但由于我不是这两个图书馆的专家,我找到了一个可行的解决方案。也许还有另一种使用PDFBox的解决方案,可以创建更小的PDF文件。也许不是。也许iText在这方面更适合我的需要。我只是想从这两种工具的专家那里得到一些帮助。这就提出了一个问题,因为您是iText的专家,我是否有在iText中创建重复页面的最佳解决方案?PdfSmartCopy会在内存中保留某些对象的散列,例如早期版本的iText中的流和最新版本中的字体字典。每当重用对象时,我们都会添加对原始对象的引用,而不是像使用PdfCopy而不是PdfSmartCopy那样复制它。Acrobat甚至做得更好:Acrobat可以将同一字体的不同子集合并成一个更大的子集。我们还不支持,因为它涉及重写整个内容流,而不是琐碎的+需要更多的CPU/内存。您的方法生成的文件要小得多。例如,对于一个67K的原始1页文件,我运行您的代码,将副本设置为1,以获得一个78K的文件。使用我的方法,其中包含2的文件是133K。请注意,要复制具有多个页面的文档,很容易将.get0更改为该列表中所有页面的循环。我还
需要注意的是,在导入页面之前,克隆要添加的页面是最安全的。我遇到了一个麻烦。我从PDFMergeUtility.java获取了克隆代码。PDPage newPage=新PDPage COSDictionarycloner.cloneForNewDocument page.getCOSDictionary;这仍然节省了磁盘空间,可能会使用更多内存,但它避免了上面链接中详述的复杂问题。在解决PDFBOX-785后,下一个版本1.8.9应该会带来更小的文件,importPage中存在一个错误,即内容流没有被压缩。您的方法会生成更小的文件。例如,对于一个67K的原始1页文件,我运行您的代码,将副本设置为1,以获得一个78K的文件。使用我的方法,其中包含2的文件是133K。请注意,要复制具有多个页面的文档,很容易将.get0更改为该列表中所有页面的循环。我还需要注意,在导入之前克隆正在添加的页面是最安全的。我遇到了一个麻烦。我从PDFMergeUtility.java获取了克隆代码。PDPage newPage=新PDPage COSDictionarycloner.cloneForNewDocument page.getCOSDictionary;这仍然节省了磁盘空间,可能会使用更多内存,但它避免了上面链接中详述的复杂问题。解决PDFBOX-785后,下一个版本1.8.9应该会带来更小的文件,importPage中有一个错误,即内容流没有被压缩。
PDDocument samplePdf = null;
try {
samplePdf = PDDocument.load(PDF_PATH);
PDPage page = (PDPage) samplePdf.getDocumentCatalog().getAllPages().get(0);
for(int i = 0; i < COPIES; i++) {
samplePdf.importPage(page);
}
samplePdf.save(SAVE_PATH); //$NON-NLS-1$
} catch (IOException e) {
e.printStackTrace();
} catch (COSVisitorException e) {
e.printStackTrace();
}