BASKET
Search
PDFlib

blocks/pdfvt1_with_blocks

Download Java Code      Switch to PHP Code     Show Output PDF      Show Input PDF

package com.pdflib.cookbook.pdflib.blocks;


import java.text.DateFormat;

import java.text.DecimalFormat;

import java.text.NumberFormat;

import java.util.Date;

import java.util.Calendar;

import java.util.Locale;

import java.util.Random;


import com.pdflib.pdflib;

import com.pdflib.PDFlibException;


/**

 * Create PDF/VT-1 with Blocks

 *

 * Create a large number of invoices in a single PDF and make use of

 * the following PDF/VT-1 features:

 * - create a document part (DPart) hierarchy

 * - assign PDF/VT scope attributes to images and imported PDF pages

 * - add document part metadata (DPM) to the DPart root node and all page nodes

 *

 * This topic is similar to starter_pdfvt1, but it uses PDFlib Blocks to

 * place various text and image items on the page.

 *

 * Required software: PPS 9

 * Required data: PDF background, fonts, several raster images

 *

 * @version $Id: pdfvt1_with_blocks.java,v 1.8 2016/12/23 09:30:47 tm Exp $

 */

public class pdfvt1_with_blocks {


    final static Random random = new Random();


    static class articledata_s {

        articledata_s(String name, double price) {

            this.name = name;

            this.price = price;

        }


        String name;

        double price;

    };


    static class addressdata_s {

        addressdata_s(String firstname, String lastname, String flat,

            String street, String city) {

            this.firstname = firstname;

            this.lastname = lastname;

            this.flat = flat;

            this.street = street;

            this.city = city;

        }


        String firstname;

        String lastname;

        String flat;

        String street;

        String city;

    };


    static final int MATRIXROWS = 32;

    static final int MATRIXDATASIZE = 4 * MATRIXROWS;


    public static void main(String argv[]) {

        int MAXRECORD = 100;

        int i, stationery, page;

        int record;

        int barcodeimage;

        String stationeryfilename = "stationery_pdfx4p.pdf";

        String fontname = "LinLibertine_R";


        /*

         * This is where font/image/PDF input files live. Adjust as necessary.

         */

        String searchpath = "../input";

        String title = "Create PDF/VT-1 with Blocks";

        String outfile = "pdfvt1_with_blocks.pdf";

        double left = 55;

        double right = 530;

        double bottom = 822;


        double fontsize = 12;

        String buf;

        String optlist;

        String fontoptions;


        String closingtext = "Terms of payment: <save fillcolor={cmyk 0 1 1 0}>30 days net<restore>. "

            + "90 days warranty starting at the day of sale. "

            + "This warranty covers defects in workmanship only. "

            + "Kraxi Systems, Inc. will, at its option, repair or replace the "

            + "product under the warranty. This warranty is not transferable. "

            + "No returns or exchanges will be accepted for wet products.";


        articledata_s articledata[] = { new articledata_s("Super Kite", 20),

            new articledata_s("Turbo Flyer", 40),

            new articledata_s("Giga Trash", 180),

            new articledata_s("Bare Bone Kit", 50),

            new articledata_s("Nitty Gritty", 20),

            new articledata_s("Pretty Dark Flyer", 75),

            new articledata_s("Large Hadron Glider", 85),

            new articledata_s("Flying Bat", 25),

            new articledata_s("Simple Dimple", 40),

            new articledata_s("Mega Sail", 95),

            new articledata_s("Tiny Tin", 25),

            new articledata_s("Monster Duck", 275),

            new articledata_s("Free Gift", 0) };


        addressdata_s addressdata[] = {

            new addressdata_s("Edith", "Poulard", "Suite C", "Main Street",

                "New York"),

            new addressdata_s("Max", "Huber", "", "Lipton Avenue",

                "Albuquerque"),

            new addressdata_s("Herbert", "Pakard", "App. 29", "Easel",

                "Duckberg"),

            new addressdata_s("Charles", "Fever", "Office 3", "Scenic Drive",

                "Los Angeles"),

            new addressdata_s("D.", "Milliband", "", "Old Harbour", "Westland"),

            new addressdata_s("Lizzy", "Tin", "Workshop", "Ford", "Detroit"),

            new addressdata_s("Patrick", "Black", "Backside",

                "Woolworth Street", "Clover") };


        String[] salesrepnames = { "Charles Ragner", "Hugo Baldwin",

            "Katie Blomock", "Ernie Bastel", "Lucy Irwin", "Bob Montagnier",

            "Chuck Hope", "Pierre Richard" };


        int salesrepimage[] = new int[salesrepnames.length];


        String[] headers = { "ITEM", "DESCRIPTION", "QUANTITY", "PRICE",

            "AMOUNT" };


        String[] alignments = { "right", "left", "right", "right", "right" };


        int dpm = 0, cip4_root, cip4_metadata;

        int exitcode = 0;


        double leading = fontsize + 2;

       

        pdflib p = null;


        try {

            p = new pdflib();


            if (p.begin_document(outfile,

                "pdfx=PDF/X-4 pdfvt=PDF/VT-1 usestransparency=false "

                    + "nodenamelist={root recipient} recordlevel=1") == -1) {

                throw new Exception("Error: " + p.get_errmsg());

            }


            /*

             * Set errorpoliy to return, this means we must check return values

             * of load_font() etc. Set the search path for fonts and images etc.

             */

            p.set_option("errorpolicy=return SearchPath={" + searchpath + "}");


            p.set_info("Creator", "PDFlib Cookbook");

            p.set_info("Title", title + " $Revision: 1.8 $");


            fontoptions = "fontname=" + fontname + " fontsize=" + fontsize

                + " embedding encoding=unicode";


            /* Define output intent profile */

            if (p.load_iccprofile("ISOcoated_v2_eci.icc",

                "usage=outputintent") == -1) {

                System.err.println("Error: " + p.get_errmsg());

                System.err.println("See www.pdflib.com for ICC profiles.");

                p.delete();

                System.exit(2);

            }


            /*

             * Load company stationery as background (used on first page for

             * each recipient)

             */

            stationery = p.open_pdi_document(stationeryfilename, "");

            if (stationery == -1) {

                throw new Exception("Error: " + p.get_errmsg());

            }


            page = p.open_pdi_page(stationery, 1,

                "pdfvt={scope=global environment={Kraxi Systems}}");

            if (page == -1) {

                throw new Exception("Error: " + p.get_errmsg());

            }


            /*

             * Preload images of all local sales reps (used on first page

             * for each recipient). To get encapsulated image XObjects, the

             * renderingintent option is used.

             */

            for (i = 0; i < salesrepnames.length; i++) {

                String salesrepfilename = "sales_rep" + i + ".jpg";

                salesrepimage[i] = p.load_image("auto", salesrepfilename,

                    "pdfvt={scope=file} renderingintent=Perceptual");


                if (salesrepimage[i] == -1) {

                    throw new Exception("Error: " + p.get_errmsg());

                }

            }


            final int ARTICLECOUNT = articledata.length;

            final int ADDRESSCOUNT = addressdata.length;

            final int COLUMNCOUNT = headers.length;

            final int SALESREPS = salesrepnames.length;


            /*

             * Construct DPM metadata for the DPart root node

             */

            cip4_metadata = p.poca_new("containertype=dict usage=dpm");

            p.poca_insert(cip4_metadata,

                "type=string key=CIP4_Conformance value=base");

            p.poca_insert(cip4_metadata,

                "type=string key=CIP4_Creator value=pdfvt1_with_blocks");

            p.poca_insert(cip4_metadata,

                "type=string key=CIP4_JobID value={Kraxi Systems invoice}");


            optlist = "containertype=dict usage=dpm "

                + "type=dict key=CIP4_Metadata value=" + cip4_metadata;

            cip4_root = p.poca_new(optlist);


            optlist = "containertype=dict usage=dpm "

                + "type=dict key=CIP4_Root value=" + cip4_root;

            dpm = p.poca_new(optlist);


            /* Create root node in the DPart hierarchy and add DPM metadata */

            optlist = "dpm=" + dpm;

            p.begin_dpart(optlist);


            p.poca_delete(dpm, "recursive=true");


            DecimalFormat zip_code_format = new DecimalFormat("00000");


            NumberFormat priceFormat = NumberFormat.getInstance(Locale.US);

            priceFormat.setMaximumFractionDigits(2);

            priceFormat.setMinimumFractionDigits(2);


            for (record = 0; record < MAXRECORD; record++) {

                byte datamatrix[] = new byte[MATRIXDATASIZE];

                int cip4_recipient, cip4_contact, cip4_person;

                String firstname, lastname, result;

                int pagecount = 0;

                int item;


                firstname = addressdata[get_random(ADDRESSCOUNT)].firstname;

                lastname = addressdata[get_random(ADDRESSCOUNT)].lastname;


                /*

                 * Construct DPM metadata for the next DPart node

                 * (i.e. the page)

                 */

                dpm = p.poca_new("containertype=dict usage=dpm");

                cip4_root = p.poca_new("containertype=dict usage=dpm");

                cip4_recipient = p.poca_new("containertype=dict usage=dpm");

                cip4_contact = p.poca_new("containertype=dict usage=dpm");

                cip4_person = p.poca_new("containertype=dict usage=dpm");


                optlist = "type=dict key=CIP4_Root value=" + cip4_root;

                p.poca_insert(dpm, optlist);


                optlist = "type=dict key=CIP4_Recipient value="

                    + cip4_recipient;

                p.poca_insert(cip4_root, optlist);


                optlist = "type=string key=CIP4_UniqueID value={ID_" + record

                    + "}";

                p.poca_insert(cip4_recipient, optlist);


                optlist = "type=dict key=CIP4_Contact value=" + cip4_contact;

                p.poca_insert(cip4_recipient, optlist);


                optlist = "type=dict key=CIP4_Person value=" + cip4_person;

                p.poca_insert(cip4_contact, optlist);


                optlist = "type=string key=CIP4_Firstname value={" + firstname

                    + "}";

                p.poca_insert(cip4_person, optlist);


                optlist = "type=string key=CIP4_Lastname value={" + lastname

                    + "}";

                p.poca_insert(cip4_person, optlist);


                /*

                 * Create a new node in the document part hierarchy and add DPM

                 * metadata

                 */

                optlist = "dpm=" + dpm;

                p.begin_dpart(optlist);


                p.poca_delete(dpm, "recursive=true");


                /*

                 * Create and place table with article list

                 */

               

                /* Header row */

                int row = 1, col;

                int tbl = -1;


                for (col = 1; col <= COLUMNCOUNT; col++) {

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} margin=2";

                    tbl = p.add_table_cell(tbl, col, row, headers[col - 1],

                        optlist);

                }

                row++;


                /* Data rows: one for each article */

                double total = 0;


                /*

                 * Print variable-length article list

                 */

                for (i = 0, item = 0; i < ARTICLECOUNT; i++) {

                    int quantity = get_random(9) + 1;

                    double sum;


                    if ((get_random(2) % 2) != 0)

                        continue;


                    col = 1;


                    item++;

                    sum = articledata[i].price * quantity;


                    /* column 1: ITEM */

                    buf = "" + item;

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} colwidth=5% margin=2";

                    tbl = p.add_table_cell(tbl, col++, row, buf, optlist);


                    /* column 2: DESCRIPTION */

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} colwidth=50% margin=2";

                    tbl = p.add_table_cell(tbl, col++, row, articledata[i].name,

                        optlist);


                    /* column 3: QUANTITY */

                    buf = "" + quantity;

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} margin=2";

                    tbl = p.add_table_cell(tbl, col++, row, buf, optlist);


                    /* column 4: PRICE */

                    buf = priceFormat.format(articledata[i].price);

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} margin=2";

                    tbl = p.add_table_cell(tbl, col++, row, buf, optlist);


                    /* column 5: AMOUNT */

                    buf = priceFormat.format(sum);

                    optlist = "fittextline={position={" + alignments[col - 1]

                        + " center} " + fontoptions + "} margin=2";

                    tbl = p.add_table_cell(tbl, col++, row, buf, optlist);


                    total += sum;

                    row++;

                }


                /* Print total in the rightmost column */

                buf = priceFormat.format(total);

                optlist = "fittextline={position={"

                    + alignments[COLUMNCOUNT - 1] + " center} " + fontoptions

                    + "} margin=2";

                tbl = p.add_table_cell(tbl, COLUMNCOUNT, row++, buf, optlist);


                /* Footer row with terms of payment */

                optlist = fontoptions + " alignment=justify leading=120%";

                int tf = p.create_textflow(closingtext, optlist);


                optlist = "rowheight=1 margin=2 margintop=" + 2 * fontsize

                    + " textflow=" + tf + " colspan=" + COLUMNCOUNT;

                tbl = p.add_table_cell(tbl, 1, row++, "", optlist);


                /* Place the table instance(s), creating pages as required */

                do {

                    double top = 100; // estimate value


                    p.begin_page_ext(0, 0,

                        "topdown=true width=a4.width height=a4.height");


                    if (++pagecount == 1) {

                        /*

                         * Place company stationery as background on first page

                         * for each recipient

                         */

                        p.fit_pdi_page(page, 0, 842, "");


                        /*

                         * Fill Blocks with name and image of local sales rep on

                         * first page for each recipient

                         */


                        optlist = "encoding=winansi embedding";

                        buf = "Local sales rep:" + "\n"

                            + salesrepnames[record % SALESREPS];

                        if (p.fill_textblock(page, "salesrepname", buf,

                            optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        if (p.fill_imageblock(page, "salesrepimage",

                            salesrepimage[record % SALESREPS], "") == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        /*

                         * Fill Text Blocks with recipient's address

                         */

                        optlist = "encoding=winansi embedding";


                        buf = firstname + " " + lastname;

                        if (p.fill_textblock(page, "name", buf, optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        buf = addressdata[get_random(ADDRESSCOUNT)].flat;

                        if (p.fill_textblock(page, "flat", buf, optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        buf = get_random(999) + " "

                            + addressdata[get_random(ADDRESSCOUNT)].street;

                        if (p.fill_textblock(page, "street", buf,

                            optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        buf = zip_code_format.format(get_random(99999)) + " "

                            + addressdata[get_random(ADDRESSCOUNT)].city;

                        if (p.fill_textblock(page, "city", buf, optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        /*

                         * Fill image Block with barcode image for each

                         * recipient. To get encapsulated image XObjects the

                         * renderingintent option is used.

                         */

                        create_datamatrix(datamatrix, record);

                        p.create_pvf("barcode", datamatrix, "");


                        barcodeimage = p.load_image("raw", "barcode",

                            "bpc=1 components=1 width=32 height=32 invert "

                                + "pdfvt={scope=singleuse} "

                                + "renderingintent=Saturation");

                        if (barcodeimage == -1) {

                            throw new Exception("Error: " + p.get_errmsg());

                        }


                        if (p.fill_imageblock(page, "barcode", barcodeimage,

                            "") == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        p.close_image(barcodeimage);

                        p.delete_pvf("barcode");


                        /*

                         * Fill Text Blocks with header and date

                         */

                        optlist = "encoding=winansi embedding";

                        buf = "INVOICE "

                            + Calendar.getInstance().get(Calendar.YEAR) + "-"

                            + (record + 1);

                        if (p.fill_textblock(page, "invoice_number", buf,

                            optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        buf = DateFormat

                            .getDateInstance(DateFormat.LONG, Locale.US)

                            .format(new Date());

                        if (p.fill_textblock(page, "date", buf, optlist) == -1)

                            System.err.println("Warning: " + p.get_errmsg());


                        /*

                         * Retrieve y coordinate of the lowest Block

                         * "invoice_number" so that we know where subsequent

                         * data can be placed.

                         */

                        top = p.pcos_get_number(stationery,

                            "pages[0]/blocks/invoice_number/Rect[1]");


                        // adjust for topdown coordinate system

                        top = 842 - top + 2 * leading;

                    }

                    else {

                        top = 50;

                    }


                    /*

                     * Place the table on the page. Shade every other row,

                     * except the footer row.

                     */

                    result = p.fit_table(tbl, left, bottom, right, top,

                        "header=1 "

                            + "fill={{area=rowodd fillcolor={gray 0.9}} "

                            + "{area=rowlast fillcolor={gray 1}}} "

                            + "rowheightdefault=auto colwidthdefault=auto");


                    if (result.equals("_error")) {

                        throw new Exception(

                            "Couldn't place table: " + p.get_errmsg());

                    }


                    p.end_page_ext("");

                }

                while (result.equals("_boxfull"));


                p.delete_table(tbl, "");


                /* Close node in the document part hierarchy */

                p.end_dpart("");

            }


            p.close_pdi_page(page);

            p.close_pdi_document(stationery);


            for (i = 0; i < salesrepnames.length; i++) {

                p.close_image(salesrepimage[i]);

            }


            /* Close root node in the document part hierarchy */

            p.end_dpart("");


            p.end_document("");

        }

        catch (PDFlibException e) {

            System.err.println(

                "PDFlib exception occurred in pdfvt1_with_blocks sample:");

            System.err.println("[" + e.get_errnum() + "] " + e.get_apiname()

                + ": " + e.get_errmsg());

            exitcode = 1;

        }

        catch (Exception e) {

            System.err.println(e.getMessage());

            exitcode = 1;

        }

        finally {

            if (p != null) {

                p.delete();

            }

            System.exit(exitcode);

        }

    }


    /**

     * Get a pseudo random number between 0 and n-1

     */

    static int get_random(int n) {

        return random.nextInt(n);

    }


    /**

     * Simulate a datamatrix barcode

     */

    static void create_datamatrix(byte datamatrix[], int record) {

        int i;


        for (i = 0; i < MATRIXROWS; i++) {

            datamatrix[4 * i + 0] = (byte) ((0xA3 + 1 * record + 17 * i) % 0xFF);

            datamatrix[4 * i + 1] = (byte) ((0xA2 + 3 * record + 11 * i) % 0xFF);

            datamatrix[4 * i + 2] = (byte) ((0xA0 + 5 * record + 7 * i) % 0xFF);

            datamatrix[4 * i + 3] = (byte) ((0x71 + 7 * record + 9 * i) % 0xFF);

        }

        for (i = 0; i < MATRIXROWS; i++) {

            datamatrix[4 * i + 0] |= 0x80;

            datamatrix[4 * i + 2] |= 0x80;

            if ((i % 2) != 0)

                datamatrix[4 * i + 3] |= 0x01;

            else

                datamatrix[4 * i + 3] &= 0xFE;

        }

        for (i = 0; i < 4; i++) {

            datamatrix[4 * (MATRIXROWS / 2 - 1) + i] = (byte) 0xFF;

            datamatrix[4 * (MATRIXROWS - 1) + i] = (byte) 0xFF;

        }

    }

}