I have much of what I was trying to do working, but am still missing
some form fields.

I will first explain the scenario, trying to be clear.

I have a "template" pdf with 5 pages.

The first 4 pages have "normal" form fields.  By calling them
"normal" I mean The runtime values for all such fields are all short
enough to fit within the corresponding fields.

Page 5 has 1 large form field, the value of which may need more
space than is available on page 5.  If this happens, the final
output PDF should contain additional pages (6, 7, etc.) with
whatever "overflow" text from this long text value did not fit on
page 5.

What I may not have made clear earlier is that page 5 of the
template, in addition the large form field, also contains some
"normal" form fields.  These appear at the top of most of the pages
of the template (including page 5).

At runtime, I have an xfdf file with all the values for all the form
fields (including the large one).

The code below does most of what I want, except on the added pages
(6, 7, etc.) the "normal" form fields are missing.  This is because
I am creating the extra pages with PdfStamper only.  And, as the
last paragraph on page 63 of the book says, when adding a page
imported with PdfStamper.getImportedPage, all interactive features
(e.g. fields) are lost.

So, it is my understanding that: if the additional pages (6, 7,
etc.)  should include not only the text from page 5 of the 5-page
template, but also the form fields, PdfCopy should be used.  I can
not see, however, how to bring PdfCopy into the picture.

I thought perhaps I could just use PdfCopy at the very beginning, to
create a PdfImportedPage (using getImportedPage), keep that in a
variable, and then when inserting a page with PdfStamper, add the
PdfImportedPage created at the beginning with PdfCopy, using
addTemplate.  I have not been able to get that working, however, and
realize it may not be the right way to go about it.

Many of the examples with PdfCopy have the constuct
    copy.addPage(copy.getImportedPage(reader,1));
However, I see no way afterward to get the direct content for such
an added page, so that the "overflow" text of the long field value
can be added using a ColumnText object.

Thanks for any advice...

So here is the code I currently have:

try {
    // I would read the form with PdfReader.  Create a PdfStamper with
this reader.
    PdfReader  templateReader = new PdfReader(templateFileName);
    ByteArrayOutputStream baos = new ByteArrayOutputStream();

    PdfStamper stamper        = new PdfStamper(templateReader, baos);

    // 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 = stamper.getImportedPage(templateReader,5);

    // Create an XfdfReader, get the fields one by one, and set all of
them except
    // one as described in the book. Set flattening to true.
    stamper.setFormFlattening(true);
    XfdfReader dataReader = new XfdfReader(dataFileName);
    AcroFields form = stamper.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));
        }
    }

    // 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()
    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];
    PdfWriter writer = stamper.getWriter();
    int pageNo = 5;
    PdfContentByte cb = stamper.getOverContent(pageNo);
    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) ) {
        stamper.insertPage(++pageNo, PageSize.LETTER);
        cb = stamper.getOverContent(pageNo);
        cb.addTemplate(sowPage,0,0);  // add the static page as
background
        ct.setCanvas(cb);
        ct.setYLine(ury);
        status = ct.go();
    }

    stamper.close();

    // write output to file
    FileOutputStream fos = new FileOutputStream(outputFileName);
    baos.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
iText-questions@lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/itext-questions
Buy the iText book: http://itext.ugent.be/itext-in-action/

Reply via email to