2008-09-18 13 views
4

我有3个PDF文档,由我们使用,并写入磁盘遗留库在飞行中生成。我的JAVA服务器代码抓住这3个文档并将它们变成一个长的PDF文档,其中它只是文档#1中的所有页面,然后是文档#2中的所有页面,最简单的方法是什么?什么是最简单的方式合并(服务器端)的PDF文档的一个集合成一个大的PDF文档在JAVA

理想情况下我希望在内存中发生这种情况,所以我可以将它作为流返回给客户端,但将其写入磁盘也是一种选择。

回答

4

@JD OConal,谢谢你的提示,你寄给我的文章是非常过时,但它确实点我对iText。我发现这个页面解释了如何做到我需要的东西: http://java-x.blogspot.com/2006/11/merge-pdf-files-with-itext.html

感谢您的其他答案, iText.jar文件,所以我不加入任何外部的依赖关系

下面的代码我结束了写作:

public class PdfMergeHelper { 

    /** 
    * Merges the passed in PDFs, in the order that they are listed in the java.util.List. 
    * Writes the resulting PDF out to the OutputStream provided. 
    * 
    * Sample Usage: 
    * List<InputStream> pdfs = new ArrayList<InputStream>(); 
    * pdfs.add(new FileInputStream("/location/of/pdf/OQS_FRSv1.5.pdf")); 
    * pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Contract_Genericv0.5.pdf")); 
    * pdfs.add(new FileInputStream("/location/of/pdf/PPFP-Quotev0.6.pdf")); 
    * FileOutputStream output = new FileOutputStream("/location/to/write/to/merge.pdf"); 
    * PdfMergeHelper.concatPDFs(pdfs, output, true); 
    * 
    * @param streamOfPDFFiles the list of files to merge, in the order that they should be merged 
    * @param outputStream the output stream to write the merged PDF to 
    * @param paginate true if you want page numbers to appear at the bottom of each page, false otherwise 
    */ 
    public static void concatPDFs(List<InputStream> streamOfPDFFiles, OutputStream outputStream, boolean paginate) { 
     Document document = new Document(); 
     try { 
      List<InputStream> pdfs = streamOfPDFFiles; 
      List<PdfReader> readers = new ArrayList<PdfReader>(); 
      int totalPages = 0; 
      Iterator<InputStream> iteratorPDFs = pdfs.iterator(); 

      // Create Readers for the pdfs. 
      while (iteratorPDFs.hasNext()) { 
       InputStream pdf = iteratorPDFs.next(); 
       PdfReader pdfReader = new PdfReader(pdf); 
       readers.add(pdfReader); 
       totalPages += pdfReader.getNumberOfPages(); 
      } 
      // Create a writer for the outputstream 
      PdfWriter writer = PdfWriter.getInstance(document, outputStream); 

      document.open(); 
      BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.NOT_EMBEDDED); 
      PdfContentByte cb = writer.getDirectContent(); // Holds the PDF 
      // data 

      PdfImportedPage page; 
      int currentPageNumber = 0; 
      int pageOfCurrentReaderPDF = 0; 
      Iterator<PdfReader> iteratorPDFReader = readers.iterator(); 

      // Loop through the PDF files and add to the output. 
      while (iteratorPDFReader.hasNext()) { 
       PdfReader pdfReader = iteratorPDFReader.next(); 

       // Create a new page in the target for each source page. 
       while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) { 
        document.newPage(); 
        pageOfCurrentReaderPDF++; 
        currentPageNumber++; 
        page = writer.getImportedPage(pdfReader, pageOfCurrentReaderPDF); 
        cb.addTemplate(page, 0, 0); 

        // Code for pagination. 
        if (paginate) { 
         cb.beginText(); 
         cb.setFontAndSize(bf, 9); 
         cb.showTextAligned(PdfContentByte.ALIGN_CENTER, "" + currentPageNumber + " of " + totalPages, 
           520, 5, 0); 
         cb.endText(); 
        } 
       } 
       pageOfCurrentReaderPDF = 0; 
      } 
      outputStream.flush(); 
      document.close(); 
      outputStream.close(); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (document.isOpen()) { 
       document.close(); 
      } 
      try { 
       if (outputStream != null) { 
        outputStream.close(); 
       } 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
    } 
} 
2

我用过pdftk,效果很好。这是一个外部应用程序,你必须从你的Java应用程序运行。

1
+0

我强烈建议不要使用iText。他们正在进行营销/合法活动,推动(读取:威胁)人们将旧的LGPL版本升级到新的商业版本。我是OSS图书馆的mantainer,有一天我在我的邮箱中发现了一些来自itextPdf.com的非常不愉快的电子邮件。 BLAH! – Gab 2016-04-22 01:07:55

0

PDFBox是目前实现这一目标的最简单的方法,是有这使得事情的代码中调用PDFMerger工具非常容易,它只需要一个for循环和2行代码,并且全部完成:)

相关问题