PDFlib Cookbook

cookbook

pdf_import/starter_pdfimpose

Import all pages from one or more existing PDFs, and place c x r pages on each sheet of the output PDF (imposition).

Download Java Code  Switch to PHP Code  Show Output 

/*
 * PDF impose:
 * Import all pages from one more existing PDFs and place col x row pages
 * on each sheet of the output PDF (imposition). If there are annotations
 * on an imported page these are also imported and scaled or rotated as
 * required.
 * 
 * Required software: PDFlib+PDI/PPS 9
 * Required data: PDF documents
 */
package com.pdflib.cookbook.pdflib.pdf_import;

import com.pdflib.pdflib;
import com.pdflib.PDFlibException;

public class starter_pdfimpose
{
    public static void main (String argv[])
    {
        /* This is where the data files are. Adjust as necessary. */
        String searchpath = "../input";
        
        /* By default annotations are also imported. In some cases this
         * requires the Noto fonts for creating annotation appearance streams.
         * We therefore set the searchpath to also point to the font directory.
         */
        String fontpath = "../resource/font";
        String outfile = "starter_pdfimpose.pdf";
        String title = "PDF Impose";

        pdflib p = null;
        int exitcode = 0;
        String pdffiles[] =
        {
            "markup_annotations_input.pdf",
            "PLOP-datasheet.pdf",
            "pCOS-datasheet.pdf"
        };
        int i, col = 0, row = 0;
        String optlist;
        double scale = 1;          // scaling factor of a page
        double rowheight;          // row height for the page to be placed
        double colwidth;           // column width for the page to be placed

        double sheetwidth = 595;   // width of the sheet
        double sheetheight = 842;  // height of the sheet
        int maxcol=2, maxrow=2;    // maxcol x maxrow pages will be placed on one sheet

        try {
            p = new pdflib();

            p.set_option("searchpath={" + searchpath + "}");
            
            p.set_option("searchpath={" + fontpath + "}");

            /* This means we must check return values of load_font() etc. */
            p.set_option("errorpolicy=return");

            if (p.begin_document(outfile, "") == -1)
                throw new Exception("Error: " + p.get_errmsg());

            p.set_info("Creator", "PDFlib Cookbook");
            p.set_info("Title", title);
            
            /* ---------------------------------------------------------------------
             * Define the sheet width and height,  the number of rows and columns
             * and calculate the scaling factor and cell dimensions for the 
             * multi-page imposition.
             * ---------------------------------------------------------------------
             */
            if (maxrow > maxcol)
                scale = 1.0 / maxrow;
            else
                scale = 1.0 / maxcol;

            rowheight = sheetheight * scale;
            colwidth = sheetwidth * scale;

            boolean pageopen = false; // is a page open that must be closed?
            
            /* Loop over all input documents */
            for (i=0; i < pdffiles.length; i++)
            {
                int indoc, maxpage, pageno, page;

                /* Open the input PDF */
                indoc = p.open_pdi_document(pdffiles[i], "");
                if (indoc == -1){
                    System.err.println("Error: " + p.get_errmsg());
                    continue;
                }
       
                maxpage = (int) p.pcos_get_number(indoc, "length:pages");
                
                /* Loop over all pages of the input document */
                for (pageno = 1; pageno <= maxpage; pageno++)
                {
                    page = p.open_pdi_page(indoc, pageno, "");

                    if (page == -1) {
                        System.err.println("Error: " + p.get_errmsg());
                        continue;
                    }
                    
                    /* Start a new page */
                    if (!pageopen) {
                        p.begin_page_ext(sheetwidth, sheetheight, "");
                        pageopen = true;
                    }
                    
                    /* The save/restore pair is required to get an independent
                     * clipping area for each mini page. Note that clipping
                     * is not required for the imported pages, but affects
                     * the rectangle around each page. Without clipping we
                     * would have to move the rectangle a bit inside the
                     * imported page to avoid drawing outside its area.
                     */
                    p.save();
                    
                    // Clipping path for the rectangle
                    p.rect(col * colwidth, sheetheight - (row + 1) * rowheight,
                        colwidth, rowheight);
                    p.clip();

                    optlist = "boxsize={" + colwidth + " " + rowheight + "} fitmethod=meet";
                        
                    // Fit the imported page in the box
                    p.fit_pdi_page(page, col * colwidth, 
                        sheetheight - (row + 1) * rowheight, optlist);

                    p.close_pdi_page(page);
                    
                    /* Draw a frame around the mini page */ 
                    p.set_graphics_option("linewidth=" + scale);
                    p.rect(col * colwidth, sheetheight - (row + 1) * rowheight,
                        colwidth, rowheight);
                    p.stroke();
                   
                    p.restore();

                    col++;
                    
                    // Start a new row if the current row is full
                    if (col == maxcol) {
                        col = 0;
                        row++;
                    }
                    
                    // Close the page if it is full
                    if (row == maxrow) {
                        row = 0;
                        p.end_page_ext("");
                        pageopen = false;
                    }
                }
                p.close_pdi_document(indoc);
            }
            
            if (pageopen) {
                p.end_page_ext("");
            }
            
            p.end_document("");

        } catch (PDFlibException e) {
            System.err.println("PDFlib exception occurred:");
            System.err.println("[" + e.get_errnum() + "] " + e.get_apiname()
                + ": " + e.get_errmsg());
            exitcode = 1;
        } catch (Exception e) {
            System.err.println(e);
            exitcode = 1;
        } finally {
            if (p != null) {
                p.delete();
            }
            System.exit(exitcode);
        }
    }
}