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/