Skip navigation
mjp420
Currently Being Moderated

Adding text to PDF using iText instead of CFPDF

Oct 15, 2009 1:36 PM

Hi,

 

I know this may seem a bit off topic being posted here but i'm asking this board since i'm a complete JAVA noob and i figure some of you CF folk might have had to do this before.

 

Anyway, about my question...i'm already adding a watermark image to a pdf using iText (CF8) thanks to the help of fellow poster (=cfSearching=).  What i'm looking for is the best way to go about adding some text to this same pdf.  I need to add 4 lines of text (with specific font and size) and center it underneath the added image.   Does anyone have a site they could point me to as to how to add formatted text and how to get the width of that text so as to align it correctly?  I've search Google and looked at a lot of JAVA code but being a JAVA noob it's tough to figure out exactly which libs and methods can be used to do this. 

 

Any help would be greatly appreciated!

 

-Michael

 
Replies
  • Currently Being Moderated
    Oct 15, 2009 2:29 PM   in reply to mjp420

    It all depends, but from what you have described you could create a merged image (ie current image plus the text beneath it).  Then apply the merged image as the watermark.  But are the four lines of text static or dynamic and do you need to figure out how to wrap the text? Maybe you can 'rig up' an example in your favorite image program to show the desired results.

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 15, 2009 8:05 PM   in reply to mjp420

    Well, the merged image is an idea but i'd rather have it be

    actual text so that it is at least copy/paste-able if viewed

    on a computer.

     

    Ah, I see. I suggested a merged image because that would be the simplest to implement. But if you want to preserve the text "as text", obviously that would not do the trick. You could probably achieve something similar using tables. Put the image in one row/cell and the centered text in another. 

     

    Bear in mind it has been a long day, and my brain is fried But I think that should work.

     
    |
    Mark as:
  • Currently Being Moderated
    Oct 17, 2009 12:33 AM   in reply to mjp420

    The classes you need are PdfTable and PdfCell

    http://cfsearching.blogspot.com/2008/09/getting-started-with-itext-tab les.html

     

    I was curious, so I threw together a rough example. It adds the table to a pdfTemplate, then adds the watermark template to each page. The positioning and table dimensions are based on my sample data, so you will need to tweak them.  Just make sure the template dimensions are large enough to accomodate your image and text. If the dimensions are not large enough, the watermark may not be visible.

     


    <!---
        NOTES:
        1. This code uses deprecated methods for compatibility with the iText version in CF8
        2. The table dimensions and watermark positions used are for demo purposes only and should be adjusted.

        Test Files:
        PDF:   http://itextdocs.lowagie.com/examples/com/lowagie/examples/general/cop ystamp/ChapterSection.pdf
        IMAGE: http://code.google.com/apis/themes/images/beveled_purpleblue.png
    --->

    <cfscript>
        err = "";
        // TEST VALUES
        maxlinechars = 40;
        dCompany = "Google Inc";
        dName = "1600 Amphitheatre Parkway";
        dPhone = "+1 650-253-0000";
        dEmail = "someone@google.com";
       
        // simplify code by putting the watermark text values into an array
        textElements    = [ dCompany, dName, dPhone, dEmail ];
        inputFile        = ExpandPath("ChapterSection.pdf");
        outputFile        = ExpandPath("ChapterSection_Watermark_ImageWithText.pdf"); 
        imgPath        = ExpandPath("/dev/beveled_purpleblue.png");

        try {
            // initalize objects for reading and writing the pdf       
            pdfReader = createObject("java", "com.lowagie.text.pdf.PdfReader").init(inputFile);
            outStream = createObject("java", "java.io.FileOutputStream").init(outputFile);
            pdfStamper = createObject("java", "com.lowagie.text.pdf.PdfStamper").init( pdfReader, outStream );

            // get the dimension of the watermark image       
            // note: the table width and height are sample values for demo only ..
            // must ensure your dimensions are large enough to accomdate your text and image
            // otherwise the watermark may not be fully visible
            img = createObject("java", "com.lowagie.text.Image").getInstance(imgPath);
            tableWidth = img.width() + 100;
            tableHeight = img.height() + 75;
           
            // create a template for storing the table
            cb = pdfStamper.getOverContent(1);
            template = cb.createTemplate(tableWidth, tableHeight);

            // create a single column table       
            table = createObject("java", "com.lowagie.text.pdf.PdfPTable").init( 1 );
            table.setTotalWidth( tableWidth );

            // reusable objects for adding table rows
            PdfCell = createObject("java", "com.lowagie.text.pdf.PdfPCell");
            Phrase = createObject("java", "com.lowagie.text.Phrase");

            // add the watermark image to the first row       
            imageCell = PdfCell.init( img, false );
            imageCell.setBorder( PdfCell.NO_BORDER);
            imageCell.setHorizontalAlignment( PdfCell.ALIGN_CENTER );
            table.addCell( imageCell );

            // add each text element in the array to a new row
            for (x = 1; x <= arrayLen(textElements); x++) {
                textCell = PdfCell.init( Phrase.init( textElements[x] ) );
                textCell.setBorder( PdfCell.NO_BORDER );
                textCell.setHorizontalAlignment( PdfCell.ALIGN_CENTER );
                table.addCell( textCell );
            }
           
            // get the calculated table height
            table.calculateHeightsFast();
            tableHeight = table.getTotalHeight();
            table.writeSelectedRows(0, -1, 0, tableHeight, template);
            WriteOutput("Calculated tableWidth="& tableWidth &", tableHeight="& tableHeight &"<br>");

            // add the template watermark to each page
            // note: the x/yPos values are for demo only (top right) ...
            i = 0;
            totalPages = pdfReader.getNumberOfPages();
            while (i LT totalPages) {
                i = i + 1;
                content = pdfStamper.getOverContent( javacast("int", i) );
                // arbitrary positioning code
                pageSize = pdfReader.getPageSize(i);
                yPos = pageSize.height() - tableHeight - 15;
                xPos = (pageSize.width() - tableWidth) - 25;
                content.addTemplate( template, xPos, yPos );
                WriteOutput("Watermarked page "& i &" at xPos="& xPos &",yPos="& yPos &"<br>");
            }
        }
        catch (Exception e) {
            err = e;
        }
        if (IsDefined("pdfStamper")) {
                 pdfStamper.close();
        }

        if (IsDefined("outStream"))
        {
            outStream.close();
        }
    </cfscript>

    <cfdump var="#err#" label="ERROR">
     
    |
    Mark as:
  • Currently Being Moderated
    Oct 18, 2009 1:59 PM   in reply to mjp420

    FROM:   imageCell.setHorizontalAlignment(

    PdfCell.ALIGN_CENTER );

     

    Hi again,

     

    Yes, I just realized that I was originally testing the code with a later version.  So the last minute change to use PdfCell.ALIGN_CENTER did not work with CF8. It was basically a lazy short-cut, to avoid creating another object just to get the alignment constants. But I see it does not work with CF8's version of iText.

     

    The alignment constants are defined higher up in the chain: ie Elements class.  In later versions of iText you can access the constants through PdfCell because it extends => Rectangle => which implements Element (where the constants are).  But that does not seem to be the case with CF8's version.  So PdfCell.ALIGN_CENTER results in an error, because no such constant exists.

     

    What does work is to create an "Element" object and then use Element.ALIGN_CENTER:

     

    Element = createObject("java", "com.lowagie.text.Element");

    imageCell.setHorizontalAlignment( Element.ALIGN_CENTER );

    .... 

    textCell.setHorizontalAlignment( Element.ALIGN_CENTER );

     

     

    -Leigh

     
    |
    Mark as:

More Like This

  • Retrieving data ...

Bookmarked By (0)

Answers + Points = Status

  • 10 points awarded for Correct Answers
  • 5 points awarded for Helpful Answers
  • 10,000+ points
  • 1,001-10,000 points
  • 501-1,000 points
  • 5-500 points