Good humor, bad ads

2 female Boston Terrier puppies, 7 wks old, Perfect markings, 524-0960. Leave mess.

Lost: small apricot poodle. Reward. Neutered. Like one of the family.

A superb and inexpensive restaurant.

Fine food expertly served by waitresses in appetizing forms.
Dinner Special — Turkey $2.35; Chicken or Beef $2.25; Children $2.00.

For sale: an antique desk suitable for lady with thick legs and large drawers.

Four-poster bed, 101 years old. Perfect for antique lover.

Now is your chance to have your ears pierced and get an extra pair to take home, too.

Wanted: 50 girls for stripping machine operators in factory.

Wanted: Unmarried girls to pick fresh fruit and produce at night.

We do not tear your clothing with machinery. We do it carefully by hand.

For Sale. Three canaries of undermined sex.

For Sale — Eight puppies from a German Shepherd and an Alaskan Hussy.

Great Dames for sale.

Have several very old dresses from grandmother in beautiful condition.

Tired of cleaning yourself? Let me do it.

Dog for sale: eats anything and is fond of children.

Vacation Special: have your home exterminated.

Mt. Kilimanjaro, the breathtaking backdrop for the Serena Lodge.
Swim in the lovely pool while you drink it all in.

Get rid of aunts: Zap does the job in 24 hours.

Toaster: A gift that every member of the family appreciates.
Automatically burns toast.

Sheer stockings. Designed for fancy dress,
but so serviceable that lots of women wear nothing else.

Stock up and save. Limit: one.

For Rent: 6-room hated apartment.

Man, honest. Will take anything.

Wanted: chambermaid in rectory. Love in, $200 a month. References required.

Man wanted to work in dynamite factory. Must be willing to travel.

Used Cars: Why go elsewhere to be cheated? Come here first!

Christmas tag-sale. Handmade gifts for the hard-to-find person.

Wanted: Hair-cutter. Excellent growth potential.

Wanted. Man to take care of cow that does not smoke or drink.

3-year-old teacher need for pre-school. Experience preferred.

Our experienced Mom will care of your child.

Fenced yard, meals, and smacks included.

Our bikinis are exciting. They are simply the tops.

Auto Repair Service. Free pick-up and delivery.

Try us once, you’ll never go anywhere again.

Illiterate? Write today for free help.

Girl wanted to assist magician in cutting-off-head illusion. Blue Cross and salary.

Wanted. Widower with school-age children requires person to assume general housekeeping duties.
Must be capable of contributing to growth of family.

And now, the Superstore–unequaled in size, unmatched in variety, unrivaled inconvenience.

We will oil your sewing machine and adjust tension in your home for $1.00.

Reasons to go to work naked

  • Your boss is always yelling, “I wanna see your butt in here by 8:00!”
  • Can take advantage of computer monitor radiation to work on your tan.
  • Inventive way to finally meet that hunk in Human Resources.
  • “I’d love to chip in, but I left my wallet in my pants.”
  • To stop those creepy guys in Marketing from looking down your blouse.
  • You want to see if it’s like the dream.
  • So that, with a little help from Muzak, you can add “Exotic Dancer” to your exaggerated resumé.
  • People stop stealing your pens after they’ve seen where you keep them.
  • Diverts attention from the fact that you also came to work drunk.
  • Gives “bad hair day” a whole new meaning.
  • No one steals your chair.

itext page number (page x of y)

I was looking for a complete example of how to dynamically generate the page numbers when you create the pdf using iText and I couldn’t find one. This is based on the example in the iText in Action book but I added my “refactoring” if you will.

I hope this helps someone. If not, it will definitely help myself in the future :)

public abstract class BaseReportBuilder extends PdfPageEventHelper {
	protected BaseFont baseFont;
	private PdfTemplate totalPages;
	private float footerTextSize = 8f;
	private int pageNumberAlignment = Element.ALIGN_CENTER;

	public BaseReportBuilder() {
		super();
		baseFont = load("fonts", "tahoma.ttf");
	}

	private BaseFont load(String location, String fontname) {
		try {
			InputStream is = getClass().getClassLoader().getResourceAsStream(location + System.getProperty("file.separator") + fontname);

			ByteArrayOutputStream out = new ByteArrayOutputStream();
			byte buf[] = new byte[1024];

			while (true) {
				int size = is.read(buf);
				if (size < 0)
					break;
				out.write(buf, 0, size);
			}
			is.close();
			buf = out.toByteArray();
			return BaseFont.createFont(fontname, BaseFont.CP1252, true, true, buf, null);
		} catch (Exception ex) {
			return null;
		}
	}

	@Override
	public void onOpenDocument(PdfWriter writer, Document document) {
		totalPages = writer.getDirectContent().createTemplate(100, 100);
		totalPages.setBoundingBox(new Rectangle(-20, -20, 100, 100));
	}

	@Override
	public void onEndPage(PdfWriter writer, Document document) {
		PdfContentByte cb = writer.getDirectContent();
		cb.saveState();
		String text = String.format("Page %s of ", writer.getPageNumber());

		float textBase = document.bottom() - 20;
		float textSize = baseFont.getWidthPoint(text, footerTextSize);
		
		cb.beginText();
		cb.setFontAndSize(baseFont, footerTextSize);
		if(Element.ALIGN_CENTER == pageNumberAlignment) {
			cb.setTextMatrix((document.right() / 2), textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, (document.right() / 2) + textSize, textBase);
		} else if(Element.ALIGN_LEFT == pageNumberAlignment) {
			cb.setTextMatrix(document.left(), textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, document.left() + textSize, textBase);
		} else {
			float adjust = baseFont.getWidthPoint("0", footerTextSize);
			cb.setTextMatrix(document.right() - textSize - adjust, textBase);
			cb.showText(text);
			cb.endText();
			cb.addTemplate(totalPages, document.right() - adjust, textBase);
		}
		cb.restoreState();
	}

	@Override
	public void onCloseDocument(PdfWriter writer, Document document) {
		totalPages.beginText();
		totalPages.setFontAndSize(baseFont, footerTextSize);
		totalPages.setTextMatrix(0, 0);
		totalPages.showText(String.valueOf(writer.getPageNumber() - 1));
		totalPages.endText();
	}

	public void setPageNumberAlignment(int pageNumberAlignment) {
		this.pageNumberAlignment = pageNumberAlignment;
	}
}

public class PageNumberReportBuilder extends BaseReportBuilder {
	public ByteArrayOutputStream buildPage() {
		ByteArrayOutputStream stream = new ByteArrayOutputStream();
		Document document = new Document(PageSize.LETTER);
		
		try {
			PdfWriter writer = PdfWriter.getInstance(document, stream);
			writer.setPageEvent(this);
			document.open();
			// add your document stuff
		} catch(DocumentException e) {
			throw new RuntimeException(e);
		}
		
		document.close();
		return stream;
	}
}

Download the complete code example (eclipse project) along with jUnit tests where you can actually generate the PDF file.