使用itext java库

时间:2016-12-16 11:24:57

标签: java pdf itext

我正在尝试使用Java中的itextpdf库将现有的pdf文件复制到一些新文件中。我使用的是版本5.5.10的itextpdf。我在两个方面面临着不同的问题:PDFStamper和PdfCopy。当我使用PDFStamper类时,我发现虽然没有添加任何新项目,但新文件大小增加了很多。这是代码片段:

    String currFile="C:\misc\pdffiles\AcroJS.pdf" ;
    String dest = "C:\misc\pdffiles\AcroJS_copy.pdf" ;
    PdfReader reader = new PdfReader(currFile) ;
    PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
    stamper.close() ;
    reader.close() ;

一些观察结果是:7 MB(原始)到13 MB(大约,新文件),116 KB> 119 KB(约)

在复制现有的pdf文件时,我期待大致相同的文件大小。我无法弄清楚为什么尺寸会增加那么多。

我也尝试过PdfCopy类。我用PdfCopy跟踪了两种方法:

  1. 逐页复制。
  2. 在pdfcopy对象上调用setMergeFields(),然后调用pdfcopy.addDocument(reader);
  3. 但这两种方法的问题在于它从pdf文件中丢弃了一些非内容元数据,因此当Adobe Reader打开时,新的pdf正在破坏。例如,我的pdf包含字典对象PdfName.S。在这种情况下,新创建的pdf文件只有2KB(原始版本为1.6 MB),它显然意味着没有任何内容被复制到文档中并且它已被破坏。

    我原来的要求很简单:将现有的pdf复制到新的pdf文件,不增加大小,不丢弃必要的项目。显而易见它不像,复制,粘贴然后重命名。因为在下一步中,我有一些与pdf内容有关的处理。任何帮助都感激不尽。

    操作系统:Windows 10专业版 Java:1.8.101 itext:5.5.10

    感谢

1 个答案:

答案 0 :(得分:3)

使用PdfStamper

您的代码

您的代码

PdfStamper stamper = new PdfStamper(reader,new FileOutputStream(dest)) ;
stamper.close() ;

基本上告诉iText复制原始PDF 丢弃未使用的对象并使用iText的默认压缩设置

iText的默认压缩设置包括使用压缩的交叉引用和对象流(在PDF 1.5中引入),但旧的交叉引用表技术和单独压缩的对象。

另一方面,示例文件确实使用了这些技术。因此,压缩得更好。

具有完全压缩的代码

您也可以告诉iText使用这些改进的压缩技术,如下所示:

PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream);
stamper.setFullCompression();

stamper.close();

Stamping.java测试方法testStampAcroJSCompressed

这会导致文件大小小于4 MB。

带附加模式的代码

如果您希望忠实于存储对象的原始方式,您可以使用附加模式,该模式以相同方式复制原始文件,并以所谓的增量更新的形式添加更改,如下所示:

PdfReader reader = new PdfReader(resourceStream);
PdfStamper stamper = new PdfStamper(reader, outputStream, '\0', true);

stamper.close();

Stamping.java测试方法testStampAcroJSAppended

这会导致文件略大于原始文件。

使用PdfCopy

您发现了PdfCopy

  

正在丢弃一些非内容元数据

当然可以。 PdfCopy旨在将从一个PDF复制到另一个PDF,保留内容和注释,但忽略其他页级和所有文档级信息。