mflorczak
mflorczak

Reputation: 363

How merge and rotate two pdf pages to one page itext

I'm trying create java application that merge three pdf. First two pdf I combine normal without resize and rotate. The last one pdf I want to rotate and place two pdf page into one pdf page.

I used iText 5.5.13. I tried merge two pdf and It's works.

public void mergePdf(List<File> pdfFiles, File outputFile) {
    try {
        Document document = new Document();
        FileOutputStream outputStream = new FileOutputStream(outputFile);
        PdfCopy copy = new PdfSmartCopy(document, outputStream);
        document.open();
        for (File inFile : pdfFiles) {
            PdfReader reader = new PdfReader(inFile.getAbsolutePath());
            copy.addDocument(reader);
            reader.close();
        }
        document.close();
    } catch (DocumentException | IOException ex) {
        ex.printStackTrace();
    }
}

I don't know how merge with rotate and resize two page into one pdf page.

Upvotes: 3

Views: 1802

Answers (2)

Mark Storer
Mark Storer

Reputation: 15868

In general, you want to turn each page into a XObject (the PdfImportedPage in @mflorczak's answer), and draw two of them into a single page.

If you know in advance that all the pages are the same size and shape, then you can get away with deciding in advance and hard-coding how you want them to appear. If not, you need to be able to hand a potentially VAST number of combinations in a general way.

This is called "N-up" printing, and there's plenty written about it around the internet if you'd like to learn more. Your particular example is "2-up" printing.

  1. get the sizes of the pages you want to merge
  2. create a new page in your output doc large enough to hold them both
  3. Create PdfImportedPages of the pages you want to import
  4. Draw the imported pages with the alignment and rotation you desire on the output page's PdfContentByte.
  5. Goto 1
  6. Unreachable
  7. Profit!

You may want to experiment with the scales and offsets (and possibly the rotation) as vs what is provided in @mflorczak's answer, and the above general theory should help to guide you. PdfImportedPage should insulate you from the source pages' rotation[s], such that you'll only need to take into account their effect borders.

Upvotes: 2

mflorczak
mflorczak

Reputation: 363

Merge:

public void mergeTwoPagesIntoOne(String originalPdfFile, String outputPdfFile) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(originalPdfFile);
    Document doc = new Document(new RectangleReadOnly(842f, 595f), 0, 0, 0, 0);
    PdfWriter writer = PdfWriter.getInstance(doc, new FileOutputStream(outputPdfFile));
    doc.open();
    int totalPages = reader.getNumberOfPages();
    for (int i = 1; i <= totalPages; i = i + 2) {
        doc.newPage();
        PdfContentByte cb = writer.getDirectContent();
        PdfImportedPage page = writer.getImportedPage(reader, i); // page #1

        float documentWidth = doc.getPageSize().getWidth() / 2;
        float documentHeight = doc.getPageSize().getHeight();
        if (i > 1)
            documentHeight = documentHeight - 50f;

        float pageWidth = page.getWidth();
        float pageHeight = page.getHeight();

        float widthScale = documentWidth / pageWidth;
        float heightScale = documentHeight / pageHeight;
        float scale = Math.min(widthScale, heightScale);

        float offsetX = (documentWidth - (pageWidth * scale)) / 2;
        float offsetY = 0f;

        cb.addTemplate(page, scale, 0, 0, scale, offsetX, offsetY);

        if (i+1 <= totalPages) {
            PdfImportedPage page2 = writer.getImportedPage(reader, i+1); // page #2

            pageWidth = page.getWidth();
            pageHeight = page.getHeight();

            widthScale = documentWidth / pageWidth;
            heightScale = documentHeight / pageHeight;
            scale = Math.min(widthScale, heightScale);

            offsetX = ((documentWidth - (pageWidth * scale)) / 2) + documentWidth;
            cb.addTemplate(page2, scale, 0, 0, scale, offsetX, offsetY);
        }
    }
    doc.close();
}

Rotate:

    public void rotatePdf(String originalPdfFile, String outputPdfFile, int degrees) throws IOException, DocumentException {
    PdfReader reader = new PdfReader(originalPdfFile);
    for (int i = 1; i <= reader.getNumberOfPages(); i++) {
        PdfDictionary dictionary = reader.getPageN(i);
        dictionary.put(PdfName.ROTATE, new PdfNumber(degrees));
    }
    PdfStamper stamper = new PdfStamper(reader, new FileOutputStream(outputPdfFile));
    stamper.close();
    reader.close();
}

Upvotes: 2

Related Questions