2014-02-12 53 views
2

合併後打印PDF文件時出現以下問題,PDF文檔被截斷。 有時發生這種情況是因爲文檔不是8.5 x 11 它們可能就像11 x 17.如何正確合併文檔?

我們可以讓它檢測頁面大小,然後對這些文檔使用相同的頁面大小嗎? 或者,如果沒有,是否有可能適合頁面?

以下是代碼:

package com.sumit.program; 

import java.io.FileInputStream; 
import java.io.FileOutputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.OutputStream; 
import java.util.ArrayList; 
import java.util.Iterator; 
import java.util.List; 

import com.itextpdf.text.Document; 
import com.itextpdf.text.PageSize; 
import com.itextpdf.text.Rectangle; 
import com.itextpdf.text.pdf.BaseFont; 
import com.itextpdf.text.pdf.PdfContentByte; 
import com.itextpdf.text.pdf.PdfImportedPage; 
import com.itextpdf.text.pdf.PdfReader; 
import com.itextpdf.text.pdf.PdfWriter; 

public class MergePdf { 

    public static void main(String[] args) { 
     try { 
      List<InputStream> pdfs = new ArrayList<InputStream>(); 

      pdfs.add(new FileInputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\Document1.pdf")); 
      pdfs.add(new FileInputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\Landscape.pdf"));   
      OutputStream output = new FileOutputStream("C:\\Documents and Settings\\Sumit\\Desktop\\NewEcnProject\\merge1.pdf"); 
      MergePdf.concatPDFs(pdfs, output, true); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } 
    } 

    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. 
      int i=1; 
      while (iteratorPDFs.hasNext()) { 
       InputStream pdf = iteratorPDFs.next(); 
       PdfReader pdfReader = new PdfReader(pdf); 
       System.out.println("Page size is "+pdfReader.getPageSize(1)); 
       readers.add(pdfReader); 
       totalPages += pdfReader.getNumberOfPages(); 
       i++; 
      } 
      // Create a writer for the outputstream 
      PdfWriter writer = PdfWriter.getInstance(document, outputStream); 
      writer.setCompressionLevel(9); 
      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. 
       System.out.println("No. of pages "+pdfReader.getNumberOfPages()); 
       i=0; 
       while (pageOfCurrentReaderPDF < pdfReader.getNumberOfPages()) { 
        Rectangle r=pdfReader.getPageSize(pdfReader.getPageN(pageOfCurrentReaderPDF+1)); 
        if(r.getWidth()==792.0 && r.getHeight()==612.0) 
         document.setPageSize(PageSize.A4.rotate()); 
        else 
         document.setPageSize(PageSize.A4); 
        document.newPage(); 
        pageOfCurrentReaderPDF++; 
        currentPageNumber++; 
        i++; 

        page = writer.getImportedPage(pdfReader, 
          pageOfCurrentReaderPDF); 
        System.out.println("Width is "+page.getWidth()); 
        System.out.println("Height is "+page.getHeight()); 
        cb.newlineText(); 
        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(); 
      System.out.println("Merging of Pdfs is done......."); 
     } catch (Exception e) { 
      e.printStackTrace(); 
     } finally { 
      if (document.isOpen()) 
       document.close(); 
      try { 
       if (outputStream != null) 
        outputStream.close(); 
      } catch (IOException ioe) { 
       ioe.printStackTrace(); 
      } 
     } 
    } 
} 

enter image description here

回答

-1

你可以比較你擺脫這個矩形的寬度和高度,你知道你正在使用的紙張大小。

http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfReader.html#getPageSize(int

http://api.itextpdf.com/itext/com/itextpdf/text/pdf/PdfReader.html#getPageSizeWithRotation(int

或者,你可以檢測到它,使用接下來的基本代碼:

PdfReader reader = new PdfReader(pdf); //yout.toByteArray()); 
      Rectangle psize = reader.getPageSize(1); 
      doc = new Document(psize, 0, 0, 0, 0); 

      PdfWriter writer = PdfWriter.getInstance(doc, output); 
      doc.open(); 
      PdfContentByte cb = writer.getDirectContent(); 

      for (int i = 0; i < reader.getNumberOfPages(); i++) { 
       writer.setCropBoxSize(psize); 
       PdfImportedPage page = writer.getImportedPage(reader, i + 1); 
       cb.addTemplate(page, 0, 0); 
      } 
+0

這裏使用writer.setCropBoxSize(psize)它會做什麼? –

+0

你能給我提供整個代碼嗎?此代碼snippest不適合我。 –

+0

此答案使用錯誤的方法!請參閱**官方**文檔,瞭解如何實現您想要的內容。 –

4

結合使用DocumentPdfWriter類與addTemplate()方法來合併文檔是餿主意。這不是addTemplate()方法的意思。您明確或隱式地定義了您正在使用的Document的頁面大小。隨着addTemplate()方法,您可以添加PdfImportedPage實例,

  • 當你添加新頁面相同的頁面大小和旋轉,你扔掉存在於該頁面中的所有互動,但除此之外一切都很好,
  • 當您使用不同的頁面大小和旋轉添加新頁面時,會得到您描述的結果。由於大小不同,導入的頁面和新頁面不匹配。部件被切斷,出現額外邊距,旋轉不同等。

這全部在chapter 6 of my book中進行了說明。您應該使用PdfCopy而不是PdfWriter。例如,參見FillFlattenMerge2例如:

Document document = new Document(); 
PdfCopy copy = new PdfSmartCopy(document, new FileOutputStream(dest)); 
document.open(); 
PdfReader reader; 
String line = br.readLine(); 
// loop over readers 
    // add the PDF to PdfCopy 
    reader = new PdfReader(baos.toByteArray()); 
    copy.addDocument(reader); 
    reader.close(); 
// end loop 
document.close(); 

在你的情況,你還需要添加頁碼,你可以在一個二去做到這一點,因爲在StampPageXofY例子做:

PdfReader reader = new PdfReader(src); 
int n = reader.getNumberOfPages(); 
PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(dest)); 
PdfContentByte pagecontent; 
for (int i = 0; i < n;) { 
    pagecontent = stamper.getOverContent(++i); 
    ColumnText.showTextAligned(pagecontent, Element.ALIGN_RIGHT, 
      new Phrase(String.format("page %s of %s", i, n)), 559, 806, 0); 
} 
stamper.close(); 
reader.close(); 

或者,您可以在合併時添加它們,例如MergeWithToc示例。

Document document = new Document(); 
PdfCopy copy = new PdfCopy(document, new FileOutputStream(filename)); 
PageStamp stamp; 
document.open(); 
int n; 
int pageNo = 0; 
PdfImportedPage page; 
Chunk chunk; 
for (Map.Entry<String, PdfReader> entry : filesToMerge.entrySet()) { 
    n = entry.getValue().getNumberOfPages(); 
    for (int i = 0; i < n;) { 
     pageNo++; 
     page = copy.getImportedPage(entry.getValue(), ++i); 
     stamp = copy.createPageStamp(page); 
     chunk = new Chunk(String.format("Page %d", pageNo)); 
     if (i == 1) 
      chunk.setLocalDestination("p" + pageNo); 
     ColumnText.showTextAligned(stamp.getUnderContent(), 
       Element.ALIGN_RIGHT, new Phrase(chunk), 
       559, 810, 0); 
     stamp.alterContents(); 
     copy.addPage(page); 
    } 
} 
document.close(); 
for (PdfReader r : filesToMerge.values()) { 
    r.close(); 
} 
reader.close(); 

我強烈建議不要使用PdfWriter合併文檔!如果您在Document課程中更改頁面大小和頁面輪轉,這不是不可能的,但是您會讓自己變得更難。此外:使用PdfWriter還會拋棄您正在合併的頁面中存在的所有交互性(鏈接,註釋,...)。您的客戶可能會遇到這種錯誤。

+0

感謝它工作對我來說,但我想添加一些文本到底部的每個複製頁面,如「頁面1」。我能怎麼做? –

+0

還有一件事我想在任何頁面之後的中間添加新頁面,我該怎麼做? –

+0

在我的回答中解釋了爲每個複製的頁面添加內容:使用「PageStamp」。在任何頁面之後在中間添加新頁面:請解釋您的意思,因爲問題不明確。爲此創建一個新問題。評論不是添加新問題的地方。如果答案回答了問題:請接受它。如果您有更多問題,請創建一個新問題。 –