BASKET
Search
PDFlib

table/table_timesheet

Download Java Code        Switch to PHP Code      Show Output PDF

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

 * Table time:

 * Create a monthly time sheet for the working hours of an employee

 *

 * Create a table with one row for each day of the month. Each row has several

 * columns representing various projects. In a cell the working hours for one or

 * more tasks are added, related to the respective day and project.

 *

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

 * Required data: none

 */

package com.pdflib.cookbook.pdflib.table;


import com.pdflib.pdflib;

import com.pdflib.PDFlibException;


public class table_timesheet

{

    public static void main (String argv[])

    {

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

    String searchpath = "../input";

    String outfile = "table_timesheet.pdf";

    String title = "Table Time Sheet";

   

    pdflib p = null;


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

    int i, j, 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 rwfirst = 16, rwother = 32;

    final String leading = "120%";

 

    final int dbreak = 15;

   

    /* The table coordinates are fixed */

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

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

   

    final int tablewidth = urx - llx;

    int cwsum = 0;

   

    final int yoffset = 10;

    final int yheading = ury + yoffset;

    final int ycontinued = lly - yoffset;

           

    /* The widths of the first two columns */

    final int cwfirst = 50;

   

    final int maxdays = 31;

   

    /* Projects */

    final String projects [] =

    {

        "Project 1", "Project 2", "Project 3", "Project 4", "Project 5"

    };

   

    /* For the first five days of the month entries are made in the timesheet

     * for each of the projects defined above

     */

    final String times [][] =

    {

        /* Project 1, Project 2, Project 3, Project 4, Project 5 */

        { "5h task-001", "2h task-033", "", "", "1h task-024" },

        { "2h task-354, 2h task-099, 2h task-045, 1h task-001, 1h task-270",

          "", "", "", "" },

        { "", "2h task-354", "4h task-033", "2h task-001", "" },

        { "8h task-001", "", "", "", "" },

        { "", "2h task-033", "5h task-045, 2h task-024, 0.5h task-033", "", "" }

    };

 

    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.4 $");


        /* 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("Time Sheet", llx, yheading, "");

             

     

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

         * In the first row, add the text line cells containing the headings

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

         */

        col = 1; row = 1;

       

        /* Prepare the option list:

         * "colwidth" defines a fixed column width.

         * "rowheight" defines a fixed row height.

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

         */

        tlcell_opts = "fittextline={font=" + boldfont +

            " fontsize={capheight=" + capheight + "} position={left top}} " +

            " colwidth=" + cwfirst + " rowheight=" + rwfirst +

            " margin=" + margin;

                         

        /* Add the "Day" heading */

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

        if (tbl == -1)

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

       

        cwsum += cwfirst;

       

        /* Add the "hours" heading */

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

        if (tbl == -1)

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

       

        cwsum += cwfirst;

       

        /* Add the project headings. Those columns evenly share the remaining

         * width of the table's fitbox.

         */

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

            tlcell_opts = "fittextline={font=" + boldfont +

                " fontsize={capheight=" + capheight + "} position={left top}}" +

                " rowheight=" + rwfirst +

                " colwidth=" + ((tablewidth - cwsum) / projects.length) +

                " margin=" + margin;

       

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

            if (tbl == -1)

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

        }

       

               

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

         * In the first column add the text line cells containing the day

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

         */

        col = 1; row = 2;

       

        /* Loop over all days */

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

        {

            /* Prepare the option list for adding the text line cell */

            tlcell_opts = "fittextline={font=" + boldfont +

            " fontsize={capheight=" + capheight + "} position={left top}} " +

            " colwidth=" + cwfirst + " rowheight=" + rwother +

            " 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 day,

             * e.g. the 15th. 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 (i == dbreak)

                tlcell_opts += " return break";

       

            /* Add the text line cell */

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

                   

            if (tbl == -1)

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

        }

       

       

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

         * Add the Textflow cell containing the individual times spent for the

         * different projects

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

         */

        col = 3; row = 2;

       

        /* Prepare the option list for adding a Textflow.

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

         */

        final String tf_opts = "font=" + regularfont +

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

       

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

            for (j = 0; j < times[i].length; j++) {

                /* Add the Textflow */

                tf = p.add_textflow(-1, times[i][j], 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}".

                 * "fitmethod=auto" scales the text until it entirely fits into

                 * the cell. (You can use the "minfontsize" option to define a

                 * lower limit when scaling the text, if required.)

                 * Note that if "fitmethod=auto" is not used the row height will

                 * be increased until the text fits completely into the cell.

                 * "verticalalign=top" will place the text at the top of the

                 * cell.

                 * "rowheight" defines the row height.

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

                 * borders.

                 */

                tfcell_opts =

                    "textflow=" + tf +

                    " fittextflow={firstlinedist=capheight verticalalign=top" +

                    " fitmethod=auto}" +

                    " rowheight=" + rwother + " margin=" + margin;

       

                /* Add the table cell */

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

       

                if (tbl == -1)

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

            }

        }

         

                   

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

         * Place the table on one or more pages

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

         */


        /* Prepare the option list for fitting the table.

         * "header=1" will repeat the first row 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=1 stroke={" +

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

            "{line=vert2 linewidth=1}}";

                             

        /* 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();

            }

        }

    }

}