Java 如何减少合并pdf的大小并使用PDFBox加速合并操作?

Java 如何减少合并pdf的大小并使用PDFBox加速合并操作?,java,pdf,size,pdfbox,reduce,Java,Pdf,Size,Pdfbox,Reduce,我们使用PDFBox 2.0.17(主要原因:免费)和java 8来合并两种类型的PDF文档(普通PDF/A和从Tiff文件转换的PDF) 我们发现生成的PDF文件的大小相当大——基本上是所有PDF文件的总大小。我正试图找到一种方法来减少产生的文件大小 我找到了一个stackoverflow链接。但这似乎没有帮助 是否有任何方法可以通过以下方式减小生成的PDF的大小 字体优化、图像优化和压缩PDF压缩 import java.io.ByteArrayOutputStream; 导入java

我们使用PDFBox 2.0.17(主要原因:免费)和java 8来合并两种类型的PDF文档(普通PDF/A和从Tiff文件转换的PDF)


我们发现生成的PDF文件的大小相当大——基本上是所有PDF文件的总大小。我正试图找到一种方法来减少产生的文件大小

我找到了一个stackoverflow链接。但这似乎没有帮助

是否有任何方法可以通过以下方式减小生成的PDF的大小

  • 字体优化、图像优化和压缩PDF压缩

import java.io.ByteArrayOutputStream;
导入java.io.File;
导入java.io.FileOutputStream;
导入java.io.IOException;
导入java.util.HashMap;
导入java.util.Map;
导入org.apache.pdfbox.cos.COSBase;
导入org.apache.pdfbox.cos.cosdirectionary;
导入org.apache.pdfbox.cos.COSName;
导入org.apache.pdfbox.multipdf.PDFMergerUtility;
导入org.apache.pdfbox.pdmodel.PDDocument;
导入org.apache.pdfbox.pdmodel.PDPage;
公共类合并测试{
公共静态void main(字符串[]args)引发IOException{
File file1=新文件(“C:\\Test\\PdfBox\u Examples\\doc1.pdf”);
File file2=新文件(“C:\\Test\\PdfBox\u Examples\\doc2.pdf”);
//实例化PDFMergerUtility类
PDFMergerUtility PDFmerger=新的PDFMergerUtility();
//设置目标文件
PDFmerger.setDestinationFileName(“C:\\Test\\PdfBox\u Examples\\merged.pdf”);
//添加源文件
PDFmerger.addSource(文件1);
PDFmerger.addSource(文件2);
//合并两个文件
PDFmerger.mergeDocuments(空);
System.out.println(“文件合并”);
File File=新文件(“C:\\Test\\PdfBox\u Examples\\merged.pdf”);
PDDocument doc=PDDocument.load(文件);
Map fontFileCache=新建HashMap();
对于(int pageNumber=0;pageNumber
getItem(COSName.FONT_FILE2));
fontFile.setItem(COSName.FONT_文件2,
get(fontName.getName());
}
}
}
}
}否则{
println(“pageDictionary为空-很可能已转换为PDF
来自Tiff”);
}
}
最终ByteArrayOutputStream bas=新ByteArrayOutputStream();
单据保存(baos);
最终文件压缩=新
文件(“C:\\Test\\PdfBox\u Examples\\Test\u compressed.pdf”);
writeTo(新文件输出流(压缩));
System.out.println(“文件压缩”);
}
}

//注:我还使用tiff_1.pdf和tiff_2.pdf作为输入进行了测试。

“基本上是所有pdf的总大小”-是的,这是人们所期望的。有商业工具可以缩小尺寸。PDFBox没有此类内置功能。当它知道PDF中存在缺陷时,有时可以减小大小。“我发现了stackoverflow链接。但它似乎没有帮助。”-当您将文件与相同的对象合并时,代码会起作用,例如,同一文档的多个副本有微小的更改。对于仅仅是相似的对象,它不起作用。在我的回答中,我明确地说了。谢谢大家的反馈。我会看看它的区别,看看我们是否能负担得起。“基本上是所有PDF的总大小”——是的,这就是人们所期望的。有商业工具可以缩小尺寸。PDFBox没有此类内置功能。当它知道PDF中存在缺陷时,有时可以减小大小。“我发现了stackoverflow链接。但它似乎没有帮助。”-当您将文件与相同的对象合并时,代码会起作用,例如,同一文档的多个副本有微小的更改。对于仅仅是相似的对象,它不起作用。在我的回答中,我明确地说了。谢谢大家的反馈。我会看看它的区别,看看我们是否能负担得起。
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;

import org.apache.pdfbox.cos.COSBase;
import org.apache.pdfbox.cos.COSDictionary;
import org.apache.pdfbox.cos.COSName;
import org.apache.pdfbox.multipdf.PDFMergerUtility;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;

public class MergerTest {
 public static void main(String[] args) throws IOException {
  File file1 = new File("C:\\Test\\PdfBox_Examples\\doc1.pdf");        
  File file2 = new File("C:\\Test\\PdfBox_Examples\\doc2.pdf");  

  //Instantiating PDFMergerUtility class
  PDFMergerUtility PDFmerger = new PDFMergerUtility();

  //Setting the destination file
PDFmerger.setDestinationFileName("C:\\Test\\PdfBox_Examples\\merged.pdf");

  //adding the source files
  PDFmerger.addSource(file1);
  PDFmerger.addSource(file2);

  //Merging the two documents
  PDFmerger.mergeDocuments(null);

  System.out.println("Documents merged");

  File file = new File("C:\\Test\\PdfBox_Examples\\merged.pdf");
  PDDocument doc = PDDocument.load(file);
  Map<String, COSBase> fontFileCache = new HashMap<>();
  for (int pageNumber = 0; pageNumber < doc.getNumberOfPages(); 
      pageNumber++) {
      final PDPage page = doc.getPage(pageNumber);
      COSDictionary pageDictionary = (COSDictionary) 
      page.getResources().getCOSObject().getDictionaryObject
      (COSName.FONT);
      if(pageDictionary !=null) {
          for (COSName currentFont : pageDictionary.keySet()) {
              COSDictionary fontDictionary = (COSDictionary) 
         pageDictionary.getDictionaryObject(currentFont);
              for (COSName actualFont : fontDictionary.keySet()) {
                  COSBase actualFontDictionaryObject = 
      fontDictionary.getDictionaryObject(actualFont);
                  if (actualFontDictionaryObject instanceof COSDictionary) 
          {
                      COSDictionary fontFile = (COSDictionary) 
           actualFontDictionaryObject;
                      if (fontFile.getItem(COSName.FONT_NAME) instanceof 
           COSName) {
                          COSName fontName = (COSName) 
                fontFile.getItem(COSName.FONT_NAME);

             fontFileCache.computeIfAbsent(fontName.getName(), key -> 
               fontFile.getItem(COSName.FONT_FILE2));
                          fontFile.setItem(COSName.FONT_FILE2, 
                     fontFileCache.get(fontName.getName()));
                      }
                  }
              }
          }
      }else {

         System.out.println("pageDictionary is null - likely Converted PDF 
           from Tiff");
      }
  }

  final ByteArrayOutputStream baos = new ByteArrayOutputStream();
  doc.save(baos);
  final File compressed = new 
      File("C:\\Test\\PdfBox_Examples\\test_compressed.pdf");
  baos.writeTo(new FileOutputStream(compressed));

  System.out.println("Documents compressed");

 }
 }