2014-02-12 4 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

Здесь u r используя writer.setCropBoxSize (psize), что он будет делать? –

+0

Можете ли вы предоставить мне весь код? Этот снимок кода не работает для меня. –

+0

Этот ответ использует неправильный подход! Пожалуйста, обратитесь к ** официальной ** документации, чтобы узнать, как добиться того, чего вы хотите. –

4

Использование класса Document и PdfWriter в сочетании с методом 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'. Добавление новой страницы посередине после любой страницы: пожалуйста, объясните, что вы имеете в виду, потому что вопрос не ясен. Создайте новый вопрос. Комментарии не являются местом для добавления новых вопросов. Если ответ ответил на вопрос: пожалуйста, примите его. Если у вас есть дополнительные вопросы, пожалуйста, создайте новый вопрос. –

Смежные вопросы