2014-02-12 45 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”。在任何页面之后在中间添加新页面:请解释您的意思,因为问题不明确。为此创建一个新问题。评论不是添加新问题的地方。如果答案回答了问题:请接受它。如果您有更多问题,请创建一个新问题。 –