2008-09-18 15 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行代碼,並且全部完成:)

相關問題