PDFlib
BASKET
PDFlib

table/table_schedule

Download Java Code      Show Output PDF        Switch to PHP Code

/* $Id: table_schedule.java,v 1.6 2013/01/15 10:12:07 stm Exp $

 * Table schedule:

 * Create a weekly booking plan for the meeting rooms of a company

 *

 * For the weekly bookings of the meeting rooms in a company, create a table

 * with each cell representing a period of time on a day of the week for a

 * certain meeting room. If a meeting room is booked for a certain period of

 * time on a certain day of the week the corresponding cells will be colorized

 * and provided with some booking text.

 * Use the "colwidth" and "rowheight" options of add_table_cell() to create the

 * table as a kind of grid with unique and fixed column width and row height.

 * Use the "fitmethod=auto" option to decrease the font size if the booking text

 * is too large to fit completely into the cell.

 * Use the "matchbox" option of add_table_cell() to colorize cells.

 *

 * The table is to be spread over two pages with a defined row being the last

 * one on the first page. Use the "return" option of add_table_cell() to force

 * fit_table() to a break after having placed the last row containing the cell.

 * 

 * Required software: PDFlib/PDFlib+PDI/PPS 9

 * Required data: none

 */

package com.pdflib.cookbook.pdflib.table;


import java.math.BigDecimal;

import java.text.NumberFormat;

import java.util.Locale;


import com.pdflib.pdflib;

import com.pdflib.PDFlibException;


public class table_schedule

{

    public static void main (String argv[])

    {

    /* This is where the data files are. Adjust as necessary. */

    String searchpath = "../input";

    String outfile = "table_schedule.pdf";

    String title = "Table Schedule";

   

    pdflib p = null;


    int row, col, tf=-1, tbl=-1;

    int i, j, t, regularfont, boldfont;

 

    String tlcell_opts;

    String fittab_opts, tfcell_opts;

 

    String result;

 

    final double pagewidth = 842, pageheight = 595;

    final double fontsize = 12;

    final double capheight = 8.5;

    final int margin = 4;

    final double rowheight1 = 16, rowheight2 = 32;

    final String leading = "120%";

 

    final int dayspan = 5, timespan=3, mroomspan = 2, croomspan=3;

    final double tstart = 5, tend = 22, tbreak = 12;

   

    /* The table coordinates are fixed */

    final int llx = 50, urx = (int) pagewidth - llx;

    final int lly = 120, ury = (int) pageheight - lly;

   

    final int yoffset = 15;

    final int yheading = ury + 2 * yoffset;

    final int ycontinued = lly - yoffset;

           

    /* The widths of the first and the other columns is fixed */

    final int cwfirst = 50, cwother = 30;

   

    final int maxdays = 6;

   

    final String days [] = {

        "Monday", "Tuesday", "Wednesday", "Thursday", "Friday", "Saturday"

    };

   

    final int maxrooms = 5;

   

    final String rooms [] = {

        "M1", "M2", "C1", "C2", "C3"

    };

   

    final int idxDay = 0, idxStart = 1, idxEnd = 2, idxRoom = 3;

    final int idxText = 4, idxColor = 5;

   

    final int maxbookings = 6;

   

    final String bookings [] [] = {

    /*   day, start, end,  room, text,                  color */

        {"1", "8",   "12", "1""Company Meeting",     "rgb 0.8 0.36 0.36"},

        {"2", "11""20", "4""Technical Workgroup", "rgb 1.0 0.84 0.0"},

        {"4", "8",   "16", "2""QM Meeting",          "rgb 0.0 0.8 0.82"},

        {"5", "10""12", "4""Admin Training",      "rgb 0.6 0.8 0.92"},

        {"5", "14""18", "4""Admin Training",      "rgb 0.6 0.8 0.92"},

        {"6", "14""22", "5""Admin Training",      "rgb 0.6 0.8 0.92"}

     };


 

    try {

        p = new pdflib();


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

       

        /* 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 + " $Revision: 1.6 $");


        /* Load the bold and regular styles of a font */

        boldfont = p.load_font("Helvetica-Bold", "unicode", "");

        if (boldfont == -1)

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

       

        regularfont = p.load_font("Helvetica", "unicode", "");

        if (regularfont == -1)

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

       

        /* Start the output page */

        p.begin_page_ext(pagewidth, pageheight, "");


        /* Output the heading */

        p.setfont(boldfont, fontsize);

        p.fit_textline("Booking Schedule", llx, yheading, "");

             

        /* Prepare the general option list for adding a Textflow.

         * For an exact vertical alignment of Textflow and text lines note the

         * following:

         * The height of an uppercase letter is exactly represented by the

         * capheight value of the font. For this reason use the capheight in the

         * font size specification. For example, a capheight of 8.5 will

         * approximately result in a font size of 12 points.

         * "alignment=center" centers the text.

         * "leading" specifies the distance between to text lines.

         */

        final String tf_opts = "font=" + regularfont + " alignment=center" +

            " fontsize={capheight=" + capheight + "} leading=" + leading;



        /* -------------------------------------------------------------------

         * Add the Textflow cell containing the time heading which spans three

         * rows

         * -------------------------------------------------------------------

         */

        col = 1; row = 1;

       

        /* Add the Textflow to be placed in the heading cell */

        tf = p.add_textflow(-1, "Time\nfrom\nto", tf_opts);

        if (tf == -1)

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

       

        /* Prepare the option list for adding the Textflow cell

         *

         * The first line of the Textflow should be aligned with the baseline of

         * the text lines. At the same time, the text lines should have the same

         * distance from the top cell border as the Textflow. To avoid any space

         * from the top add the Textflow cell using

         * "fittextflow={firstlinedist=capheight}".

         * "colwidth" defines the width of the first column the cell is spanned.

         * "rowheight" defines the row height.

         * "margin" adds some empty space between the text and the cell borders.

         * "colspan" defines the number of columns the cell is spanned.

         */

        tfcell_opts =

            "textflow=" + tf +

            " fittextflow={firstlinedist=capheight fitmethod=auto}" +

            " colwidth=" + cwfirst +

            " rowheight=" + rowheight1 +

            " margin=" + margin +

            " rowspan=" + timespan;

       

        tbl = p.add_table_cell(tbl, col, row, "", tfcell_opts);

       

        if (tbl == -1)

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

       

             

        /* -------------------------------------------------------------------

         * Add the text line cells containing the days of the week headings in

         * the first row, spanning several columns each

         * -------------------------------------------------------------------

         */

        col = 2; row = 1;

       

        /* Prepare the option list:

         * "position={center top}" positions the text on the top left.

         * "fitmethod=auto" decreases the font size of the text if it is too

         * large to fit completely into the cell instead of increasing the row

         * height.

         * The height of an uppercase letter is exactly represented by the

         * capheight value of the font. For this reason use the capheight in the

         * font size specification. For example, to match a row height of 16,

         * you could use a capheight of 8.5 and a margin of 4.

         * "fitmethod=auto" will decrease the font size, if necessary, until the

         * text line fits completely into the cell.

         * "colwidth" defines the width of the first column the cell is spanned.

         * "rowheight" defines the row height.

         * "margin" adds some empty space between the text and the cell borders.

         * "colspan" defines the number of columns the cell is spanned.

         */

        tlcell_opts = "fittextline={position={center top} fitmethod=auto" +

        " font=" + boldfont + " fontsize={capheight=" + capheight + "}} " +

        " colwidth=" + cwother +

        " rowheight=" + rowheight1 +

        " margin=" + margin +

        " colspan=" + dayspan;

                     

        /* Add the table cells containing the days of the week */

        for (i = 0; i < maxdays; i++)

        {

            tbl = p.add_table_cell(tbl, col, row, days[i], tlcell_opts);

       

            if (tbl == -1)

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

       

            col += dayspan;

        }

       

       

        /* --------------------------------------------------------------------

         * In the second row below each day of the week, add the "Meeting Room"

         * and "Conference Room" Textflow heading cells. The two cells together

         * span the same number of columns as spanned by the day of the week.

         * --------------------------------------------------------------------

         */

        col = 2; row = 2;

       

        /* Loop over the number of days of the week */

        for (i = 0; i < maxdays; i++)

        {

            /* Add the "Meeting Room" Textflow */

            tf = p.add_textflow(-1, "Meeting Room", tf_opts);

            if (tf == -1)

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

       

            /* Add the "Meeting Room" Textflow cell */

            tfcell_opts = "textflow=" + tf +

                " fittextflow={firstlinedist=capheight fitmethod=auto}" +

                " colwidth=" + cwother +

                " rowheight=" + rowheight2 +

                " margin=" + margin +

                " colspan=" + mroomspan;

                   

            tbl = p.add_table_cell(tbl, col, row, "", tfcell_opts);

       

            if (tbl == -1)

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

           

            col += mroomspan;

           

            /* Add the "Conference Room" Textflow */

            tf = p.add_textflow(-1, "Conference Room", tf_opts);

            if (tf == -1)

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

       

            /* Add the "Conference Room" Textflow cell */

            tfcell_opts = "textflow=" + tf +

            " fittextflow={firstlinedist=capheight fitmethod=auto}" +

            " colwidth=" + cwother +

            " rowheight=" + rowheight2 +

            " margin=" + margin +

            " colspan=" + croomspan;

       

            tbl = p.add_table_cell(tbl, col, row, "", tfcell_opts);

       

            if (tbl == -1)

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

           

            col += croomspan;

        }

       

       

        /* ---------------------------------------------------------------------

         * In the third row below the "Meeting Room" and "Conference Room" cells

         * for each day of the week add five text line heading cells containing

         * the names of the meeting rooms.

         * ---------------------------------------------------------------------

         */

        col = 2; row = 3;

       

        /* Prepare the option list for adding the cells */

        tlcell_opts = "fittextline={position={center top} fitmethod=auto" +

            " font=" + regularfont + " fontsize={capheight=" + capheight + "}}"+

            " colwidth=" + cwother +

            " rowheight=" + rowheight1 +

            " margin=" + margin;

     

        /* Loop over the number of days of the week */

        for (i = 0; i < maxdays; i++)

        {

            /* Add the cells with the names of the room */

            for (j = 0; j < maxrooms; j++) {

                tbl = p.add_table_cell(tbl, col++, row, rooms[j], tlcell_opts);

               

                if (tbl == -1)

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

            }

        }

       

       

        /* --------------------------------------------------------------

         * In the first column add the Textflow cells containing the time

         * intervals, one cell for each hour

         * --------------------------------------------------------------

         */

        col = 1; row = 4;

       

        /* For outputting the time of the day, initialize the maximum number

         * of fraction digits to two

         */

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

        form.setMaximumFractionDigits(2);

        form.setMinimumFractionDigits(2);

       

        /* Loop over all time intervals */

        for (i = 1, t = (int) tstart; i <= tend - tstart; i++, t++)

        {

            /* Format the current time interval to a maximum of two fraction

             * digits

             */

            BigDecimal value = new BigDecimal(t);

            BigDecimal roundedValue =

                value.setScale(2, BigDecimal.ROUND_HALF_UP);

           

            String text = roundedValue.toString() + "\n";

           

            value = new BigDecimal(t+1);

            roundedValue = value.setScale(2, BigDecimal.ROUND_HALF_UP);

            text += roundedValue.toString();

           

            /* Add the time interval Textflow */

            tf = p.add_textflow(-1, text, tf_opts);

            if (tf == -1)

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

       

            /* Prepare the option list for adding the time interval headings */

            tfcell_opts = "textflow=" + tf +

            " fittextflow={firstlinedist=capheight  fitmethod=auto}" +

            " colwidth=" + cwfirst +

            " rowheight=" + rowheight2 +

            " margin=" + margin;

           

            /* We want to spread the table over two pages. The last row placed

             * on the first page should be the one representing a defined time

             * interval, e.g. of 12-13. To accomplish this use the "return"

             * option of add_table_cell() when adding the respective cell. This

             * signals to fit_table() to return after having placed the

             * corresponding table row, and we can fit the following table rows

             * in a subsequent call on the second page.   

             */

            if (t == tbreak)

                tfcell_opts += " return break";

       

            /* Add the time interval Textflow cell */

            tbl = p.add_table_cell(tbl, col, row++, "", tfcell_opts);

                   

            if (tbl == -1)

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

        }

       

       

        /* -----------------------------------------------------------------

         * For each booking item add a text line cell containing the booking

         * text and colorize it. Place the cell according to the day of the

         * week, time interval and meeting room affected.

         * -----------------------------------------------------------------

         */

       

        /* Loop over all bookings */

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

            /* Read the attributes of the current booking */

            int start = Integer.valueOf(bookings[i][idxStart]).intValue();

            int end = Integer.valueOf(bookings[i][idxEnd]).intValue();

            int day = Integer.valueOf(bookings[i][idxDay]).intValue();

            int room = Integer.valueOf(bookings[i][idxRoom]).intValue();

            String text = bookings[i][idxText];

           

            /* Get the column and row as well as the number of rows spanned by

             * the cell

             */

            int rowspan = 1;

           

            col = 2 + ((day - 1) * dayspan) + (room - 1);

            row = 4 + (start - (int) tstart);

           

            if (end != start)

                rowspan = end - start;

           

            /* Prepare the option list for adding the booking item cell */

            String opts = "fittextline={position={center} " +

                " fitmethod=auto font=" + regularfont + " orientate=west" +

                " fontsize={capheight=" + capheight + "}} " +

                " colwidth=" + cwother +

                " rowheight=" + rowheight2 +

                " margin=" + margin +

                " rowspan=" + rowspan +

                " matchbox={fillcolor={" + bookings[i][idxColor] + "}}";

           

            tbl = p.add_table_cell(tbl, col, row, text, opts);

            if (tbl == -1)

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

        }

               

             

        /* ------------------------------------

         * Place the table on one or more pages

         * ------------------------------------

         */


        /* Prepare the option list for fitting the table.

         * "header=3" will repeat the first three rows at the beginning of

         * each new page. The "stroke" option will stroke lines with two

         * different line widths. The table frame as well as each vertical

         * line to the right of a day-of-the-week cell is stroked with a

         * line width of 1, all other lines are stroked with a line width of

         * 0.3.

         */

        fittab_opts = "header=3 stroke={" +

            "{line=frame linewidth=1} {line=other linewidth=0.3} ";

       

        for (i = 0; i < maxdays; i++)

            fittab_opts += "{line=vert" + (1+i*maxrooms) + " linewidth=1} ";     

                     

        fittab_opts += "}";

       

        /* Loop until all of the table is placed; create new pages as long as

         * more table instances need to be placed

         */

        do {

            /* Place the table instance */

            result = p.fit_table(tbl, llx, lly, urx, ury, fittab_opts);


            if (result.equals("_error"))

                throw new Exception ("Couldn't place table: " +

                    p.get_errmsg());

           

            /* A return value of "break" has been explicitly specified in

             * add_table_cell() when adding the cell for a certain time interval

             * after which a new page shall be started.

             */

            if (result.equals("_boxfull") || result.equals("break")) {

                p.setfont(regularfont, fontsize);

                p.fit_textline("-- Continued --", urx, ycontinued,

                    "position {right top}");

               

                p.end_page_ext("");

                p.begin_page_ext(pagewidth, pageheight, "");

            }

        } while (result.equals("_boxfull") || result.equals("break"));

       

        p.end_page_ext("");

       

        p.end_document("");

     

        } catch (PDFlibException e) {

            System.err.print("PDFlib exception occurred:\n");

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

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

        } catch (Exception e) {

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

        } finally {

            if (p != null) {

                p.delete();

            }

        }

    }

}