PDFlib Cookbook

cookbook

table/table_rotated_text

Download Java Code        Switch to PHP Code      Show Output PDF

/* $Id: table_rotated_text.java,v 1.4 2013/01/15 10:12:07 stm Exp $
 * Table rotated text:
 * Create a table containing rotated text
 * 
 * Create a table with rotated text lines and Textflow spanning several rows.
 * 
 * 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_rotated_text
{
    public static void main (String argv[])
    {
    /* This is where the data files are. Adjust as necessary. */
    String searchpath = "../input";
    String outfile = "table_rotated_text.pdf";
    String title = "Table Rotated Text";
    
    pdflib p = null;

    int row, tf=-1, tbl=-1;
    int i, j, regularfont, boldfont;
  
    String htlcell_opts, vtlcell_opts, tfcell_opts, tf_opts, fittab_opts;
        
    String result;
  
    final double pagewidth = 595, pageheight = 842;
    final double fontsize = 12;
    final double capheight = 8.5;
    final int margin = 4;
    final String leading = "120%";
  
    final int c_table = 1, c_numbers = 1, c_description = 4;
    final int c_models = 2, c_category = 1, c_model = 2, c_plane = 3;
    
    final int r_model = 4, r_plane = 4, r_description = 4;
    
    /* The table coordinates are fixed */
    final int llx = 50, urx = (int) pagewidth - llx;
    final int lly = 30, ury = (int) pageheight - lly;
    
    final int yoffset = 10;
    final int ycontinued = lly - yoffset;
    
    /* Row height */
    final double rowheight = 16;
           
    /* Column widths */
    final int cwfirst = 50, cwplane = 50, cwdescription = 100;
    
    final int maxcols = 4;
    
    /* Projects */
    final String models [] =
    {
        "Rockets", "Gliders", "Arrows", "Darts"
    };
    
    final String descriptions [] =
    {
        "With the paper rockets you can send all your messages even when " +
        "sitting in a hall or in the cinema pretty near the back.",
        
        "Unbelievable sailplanes! They are amazingly robust and can even do " +
        "aerobatics. But they are best suited to gliding.",
        
        "The paper arrows can be thrown with big swing. We launched it from " +
        "the roof of a hotel. It stayed in the air a long time and covered " +
        "a considerable distance.",

        "The super darts can fly giant loops with a radius of 4 or 5 meters " +
        "and can cover long distances. Its heavy cone point is slightly " +
        "bowed upwards to get the lift required for loops"
    };
    
    /* Three planes belong to each model */
    final String planes [][] =
    {
        { "Long Distance Glider", "Giant Wing", "Spider Glider" },
        { "Cone Head Rocket", "Turbo Flyer", "Red Baron" },
        { "Free Gift", "Bare Bone Kit", "Witty Kitty" },
        { "Super Dart", "Giga Trash", "Cool Carve" }
    };
  
    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, "");

        /* Prepare the general option list for horizontal and vertical text line
         * cells:
         * 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.
         * "colwidth" defines a fixed column width.
         * "rowheight" defines a fixed row height.
         * "margin" adds some empty space between the text and the cell borders.
         */
        htlcell_opts = "fittextline={font=" + boldfont + 
            " fontsize={capheight=" + capheight + "} position={left top}} " +
            " colwidth=" + cwfirst + " rowheight=" + rowheight + 
            " margin=" + margin;
        
        vtlcell_opts = "fittextline={font=" + regularfont + 
            " fontsize={capheight=" + capheight + "} position={center}" +
            " orientate=west} " +
            " colwidth=" + cwfirst + " rowheight=" + rowheight + 
            " margin=" + margin;
                          
            
        /* --------------------------------------------------------------
         * In the first four rows, add the text line cells containing the
         * headings
         * --------------------------------------------------------------
         */
        row = 1;
      
        /* Add the "Plane Table" heading spanning all columns */
        tbl = p.add_table_cell(tbl, c_table, row++, "Plane Table", 
            htlcell_opts + " colspan=" + maxcols);
        if (tbl == -1)
            throw new Exception("Error adding cell: " + p.get_errmsg());
        
        /* Add the column number headings */
        for (i = c_numbers; i <= maxcols; i++) {
            tbl = p.add_table_cell(tbl, i, row, String.valueOf(i), 
                htlcell_opts);
            if (tbl == -1)
                throw new Exception("Error adding cell: " + p.get_errmsg());
        }
        
        row++;
        
        /* Add the "Description" heading */
        tbl = p.add_table_cell(tbl, c_description, row, "Description", 
            htlcell_opts);
        if (tbl == -1)
            throw new Exception("Error adding cell: " + p.get_errmsg());
        
        /* Add the "Models" heading */
        tbl = p.add_table_cell(tbl, c_models, row++, "Models", 
            htlcell_opts + " colspan=2");
        if (tbl == -1)
            throw new Exception("Error adding cell: " + p.get_errmsg());
        
        
        /* ---------------------------------------------------------------------
         * In the first column add a heading as text line cell orientated to the
         * west and spanning as much rows as planes are available
         * ---------------------------------------------------------------------
         */
        int nplanes = planes.length * planes[0].length;
        
        tbl = p.add_table_cell(tbl, c_category, row, 
            "Paper Planes Standard Collection", 
            vtlcell_opts + " rowspan=" + nplanes);
        if (tbl == -1)
            throw new Exception("Error adding cell: " + p.get_errmsg());
        
            
        /* -------------------------------------------------------------------
         * In the second column add the individual model headings as text line
         * cells orientated to the west and spanning three rows each
         * -------------------------------------------------------------------
         */
        row = r_model;
            
        for (i = 1; i <= models.length; i++) {
            tbl = p.add_table_cell(tbl, c_model, row, models[i-1],
                vtlcell_opts + " rowspan=3");
            if (tbl == -1)
                throw new Exception("Error adding cell: " + p.get_errmsg());
            
            row += 3;           
        }
        
               
        /* --------------------------------------------------------------------
         * In the third column add the individual planes as Textflow cells with
         * all cells having the same height 
         * --------------------------------------------------------------------
         */
        row = r_plane;
        
        /* Prepare the option list for adding a Textflow.
         * "leading" specifies the distance between to text lines.
         */
        tf_opts = "font=" + regularfont + 
            " fontsize={capheight=" + capheight + "} leading=" + leading;
        
        for (i = 0; i < planes.length; i++) {
            for (j = 0; j < planes[i].length; j++) {
                /* Add the Textflow */
                tf = p.add_textflow(-1, planes[i][j], tf_opts);
                if (tf == -1)
                    throw new Exception("Error: " + p.get_errmsg());
                
                /* Prepare the option list for adding the Textflow cell 
                 * To avoid any space from the top add the Textflow cell using 
                 * "fittextflow={firstlinedist=capheight}".
                 * "verticalalign=top" will place the text at the top of the 
                 * cell.
                 * "rowheight" defines the row height, and "colwidth" specifies
                 * the column width.
                 * "margin" adds some empty space between the text and the cell 
                 * borders.
                 * "rowscalegroup=myscaling" assigns the group "myscaling" to
                 * each of the cells to ensure that all cells will be scaled to
                 * have the same height. 
                 */
                tfcell_opts = 
                    "textflow=" + tf + 
                    " fittextflow={firstlinedist=capheight verticalalign=top}" + 
                    " rowheight=" + rowheight +
                    " colwidth=" + cwplane +
                    " margin=" + margin +
                    " rowscalegroup=myscaling";
        
                /* Add the table cell */
                tbl = p.add_table_cell(tbl, c_plane, row++, "",
                    tfcell_opts);
        
                if (tbl == -1)
                    throw new Exception("Error: " + p.get_errmsg());
            }
        }
        
        
        /* -----------------------------------------------------------------
         * Add the descriptions as Textflow cells orientated to the west and
         * spanning three rows each
         * -----------------------------------------------------------------
         */
        row = r_description;
        
        /* Prepare the option list for adding a Textflow. For a description see 
         * above.
         */
        tf_opts = "font=" + regularfont + 
            " fontsize={capheight=" + capheight + "} leading=" + leading;
        
        for (i = 0; i < descriptions.length; i++) {
            /* Add the Textflow */
            tf = p.add_textflow(-1, descriptions[i], tf_opts);
            if (tf == -1)
                throw new Exception("Error: " + p.get_errmsg());
                
            /* Prepare the option list for adding the Textflow cell. 
             * "orientate=west" orientates the Textflow to the west.
             * "rowheight" and "colwidth" specify the height of the row and the 
             * width of the column.
             * "margin" adds some empty space between the text and the cell 
             * borders.
             * With "rowspan=3" the cell will span three rows.
             */
            tfcell_opts = 
                "textflow=" + tf + 
                " fittextflow={firstlinedist=capheight verticalalign=top" +
                " orientate=west}" + 
                " rowheight=" + rowheight +
                " colwidth=" + cwdescription + 
                " margin=" + margin +
                " rowspan=3";
        
            /* Add the table cell */
            tbl = p.add_table_cell(tbl, c_description, row, "", tfcell_opts);
            if (tbl == -1)
                    throw new Exception("Error: " + p.get_errmsg());
            
            row += 3;
        }
         
                    
        /* ------------------------------------
         * Place the table on one or more pages
         * ------------------------------------
         */

        /* Prepare the option list for fitting the table.
         * "header=4" will repeat the first four rows at the beginning of
         * each new page. The "stroke" option will stroke lines with two 
         * different line widths. The table frame 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} }";
                             
        /* 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();
            }
        }
    }
}