Bruno Lowagie (iText <bruno <at> lowagie.com> writes:

> So the best way to add "page X of Y" is to write a for-loop
> that gets the OverContent of every page and adds the "page
> X of Y" string at an absolute position.
> 
> There's no need to use page events, and no need to use a
> PdfTemplate object. You can add the complete String with
> the page information directly.

Bruno -- I have it working now!
This is the lion's share of some "proof of concept"
work I am doing.  We are currently using the FDFMerge
software from Appligent, but it can not handle such
overflow text as I have been dealing with here.  So
I have been looking into seeing if we can do what
we need with iText instead.  I have a few more things
to try/test, but I'm confident these will not stop us.
Thanks again for such helpfulness!

In case this might help anyone else, here is the current
code which does all:

try {
    // OK, then maybe you should do it in two passes.
    // First use PdfStamper to fill out and flatten all the fields
    // EXCEPT the large one on page 5. Don't forget to retrieve
    // the coordinates of the large field. Close the stamper.

    PdfReader reader1 = new PdfReader(templateFileName);
    ByteArrayOutputStream baos1 = new ByteArrayOutputStream();
    PdfStamper stamper1 = new PdfStamper(reader1, baos1);
    stamper1.setFormFlattening(true);

    XfdfReader dataReader = new XfdfReader(dataFileName);
    AcroFields form = stamper1.getAcroFields();
    String fieldName;
    for (Iterator i = form.getFields().keySet().iterator(); i.hasNext(); ) {
        fieldName = (String)i.next();
        if ( fieldName.equals("long_sow") ) {
            sow = dataReader.getField(fieldName);
        } else {
            form.setField(fieldName,dataReader.getField(fieldName));
        }
    }

    float[] sowFieldPositions = form.getFieldPositions("long_sow");
    if ( sowFieldPositions == null ) {
        System.err.println("no field positions found for long_sow");
        System.exit(1);
    } else if (sowFieldPositions.length != 5) {
        System.err.println("unexpected number of values for long_sow field
positions: " + sowFieldPositions.length);
        System.exit(1);
    }
    float llx = sowFieldPositions[1];
    float lly = sowFieldPositions[2];
    float urx = sowFieldPositions[3];
    float ury = sowFieldPositions[4];

    stamper1.close();

    // Now you have a PDF template that is almost completely filled in
    // (as described in chapter 2: this form doesn't need to be stored
    // on the file system; it can be stored in memory as a byte array).
    // Use this form to create a new PdfReader and PdfStamper object.
    // Use the coordinates retrieved earlier to add the content on
    // page 5. The rest is similar to what you're already doing now,
    // with as main difference that the 'normal' fields on page 5 are
    // no longer acrofields, but real content (and part of the imported
    // page).

    PdfReader reader2 = new PdfReader(baos1.toByteArray());
    ByteArrayOutputStream baos2 = new ByteArrayOutputStream();
    PdfStamper stamper2 = new PdfStamper(reader2, baos2);

    // Import the static page and add it as a background to every page (in a 
loop).
    // 5th page is the one which may need to overflow
    PdfImportedPage sowPage = stamper2.getImportedPage(reader2,5);

    // The field you didn't set, is the one that may or may not fit the last 
page.
    // Wrap the data in a ColumnText object.  Retrieve the positions of the big
    // field on the last page. Use these coordinates to define the ColumnText
    // rectangle.  Invoke go()

    int pageCt = 5;
    PdfContentByte cb = stamper2.getOverContent(pageCt);
    ColumnText ct = new ColumnText(cb);
    ct.setSimpleColumn(llx,lly,urx,ury);
    ct.setText(new Phrase(sow));
    int status = ct.go();

    // If there's no more text left in the ColumnText, you're done. The extra 
page
    // is not needed. If there still is some text left, insert a new page at the
    // end, add the static page as background, reset the ColumnText rectangle 
and
    // add it to the newly created page.

    // You should insert a new page and get a new cb from that page.
    while ( ColumnText.hasMoreText(status) ) {
        stamper2.insertPage(++pageCt, PageSize.LETTER);
        cb = stamper2.getOverContent(pageCt);
        cb.addTemplate(sowPage,0,0);  // add the static page as background
        ct.setCanvas(cb);
        ct.setYLine(ury);
        status = ct.go();
    }

    // So the best way to add "page X of Y" is to write a for-loop
    // that gets the OverContent of every page and adds the "page
    // X of Y" string at an absolute position.
    //
    // There's no need to use page events, and no need to use a
    // PdfTemplate object. You can add the complete String with
    // the page information directly.

    BaseFont bf = BaseFont.createFont(BaseFont.HELVETICA, BaseFont.WINANSI,
BaseFont.NOT_EMBEDDED);
    for (int pageNo = 1; pageNo <= pageCt; pageNo++) {
        cb = stamper2.getOverContent(pageNo);
        cb.beginText();
        cb.setFontAndSize(bf, 12);
        cb.setTextMatrix(522, 10);
        cb.showText("Page " + pageNo + " of " + pageCt);
        cb.endText();
    }

    stamper2.close();

    // write output to file
    FileOutputStream fos = new FileOutputStream(outputFileName);
    baos2.writeTo(fos);
    fos.close();
    System.out.println("done");

} catch (Exception e) {
    e.printStackTrace();
}



-------------------------------------------------------------------------
Take Surveys. Earn Cash. Influence the Future of IT
Join SourceForge.net's Techsay panel and you'll get the chance to share your
opinions on IT & business topics through brief surveys - and earn cash
http://www.techsay.com/default.php?page=join.php&p=sourceforge&CID=DEVDEV
_______________________________________________
iText-questions mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://itext.ugent.be/itext-in-action/

Reply via email to