Merge pdf documents of different width using iText

2019-01-26 14:06发布

问题:

I am having problem while merging documents of different width using iText.

Below is the code I'm using to merge.

        public static void doMerge(List<InputStream> list, OutputStream outputStream) throws Exception {

            Rectangle pagesize = new Rectangle(1700f, 20f);


            com.itextpdf.text.Document document = new com.itextpdf.text.Document(pagesize);

            PdfWriter writer = PdfWriter.getInstance(document, outputStream);
            document.open();
            document.setPageSize(pagesize);
            com.itextpdf.text.pdf.PdfContentByte cb = writer.getDirectContent();

            for (InputStream in : list){
                PdfReader reader = new PdfReader(in);
                for (int i = 1; i <= reader.getNumberOfPages(); i++){
                    document.newPage();
                    //import the page from source pdf
                    com.itextpdf.text.pdf.PdfImportedPage page = writer.getImportedPage(reader, i);

                    //calculate the y for merging it from top
                    float y = document.getPageSize().getHeight() - page.getHeight();
                    //add the page to the destination pdf

                    cb.addTemplate(page, 0, y);

                }
                reader.close();
                in.close();
            }

            outputStream.flush();
            document.close();
            outputStream.close();
        }

First page of pdf will be of 14 inch of width and 13 inch of height. All the other pages on document will be always smaller than it.

I want to merge all the documents altogether in a single document.

I don't know how to set a width and height of a single merged document.

I think Rectangle pagesize = new Rectangle(1700f, 20f); should do it but it's not working means if change it to Rectangle pagesize = new Rectangle(1700f, 200f);, document has no effect.

Please guide me further.

回答1:

Using the PdfWriter class to merge documents goes against all the recommendations given in the official documentation, though there are unofficial examples that may have lured you into writing bad code. I hope that you understand that I find these bad examples even more annoying than you do.

Please take a look at Table 6.1 in chapter 6 of my book. It gives you an overview showing when to use which class. In this case, you should use PdfCopy:

String[] files = { MovieLinks1.RESULT, MovieHistory.RESULT };
// step 1
Document document = new Document();
// step 2
PdfCopy copy = new PdfCopy(document, new FileOutputStream(RESULT));
// step 3
document.open();
// step 4
PdfReader reader;
int n;
// loop over the documents you want to concatenate
for (int i = 0; i < files.length; i++) {
    reader = new PdfReader(files[i]);
    // loop over the pages in that document
    n = reader.getNumberOfPages();
    for (int page = 0; page < n; ) {
        copy.addPage(copy.getImportedPage(reader, ++page));
    }
    copy.freeReader(reader);
    reader.close();
}
// step 5
document.close();

If you are using a recent version of iText, you can even use the addDocument() method in which case you don't need to loop over all the pages. You also need to take special care if forms are involved. There are several examples demonstrating the new functionality (dating from after the book was written) in the Sandbox.



回答2:

with the itext version 5.5 we can merge pdf more easly using the method PdfCopy.addDocument :

            package tn.com.sf.za.rd.controller;

            import java.io.FileOutputStream;
            import java.io.IOException;

            import com.itextpdf.text.Document;
            import com.itextpdf.text.DocumentException;
            import com.itextpdf.text.pdf.PdfCopy;
            import com.itextpdf.text.pdf.PdfReader;

            public class ReportMerging {

                public static void main(String[] args) throws DocumentException, IOException {

                    String DOC_ONE_PATH = "D:/s.zaghdoudi/tmp/one.pdf";
                    String DOC_TWO_PATH = "D:/s.zaghdoudi/tmp/two.pdf";
                    String DOC_THREE_PATH = "D:/s.zaghdoudi/tmp/three.pdf";
                    Document document = new Document();
                    PdfCopy copy = new PdfCopy(document, new FileOutputStream(DOC_THREE_PATH));
                    document.open();
                    PdfReader readerOne = new PdfReader(DOC_ONE_PATH);
                    PdfReader readerTwo = new PdfReader(DOC_TWO_PATH);
                    copy.addDocument(readerOne);
                    copy.addDocument(readerTwo);
                    document.close();
                }

            }