import java.io.FileOutputStream;
import java.io.IOException;

import com.itextpdf.text.Chunk;
import com.itextpdf.text.Document;
import com.itextpdf.text.DocumentException;
import com.itextpdf.text.Element;
import com.itextpdf.text.ExceptionConverter;
import com.itextpdf.text.Font;
import com.itextpdf.text.Image;
import com.itextpdf.text.Paragraph;
import com.itextpdf.text.Phrase;
import com.itextpdf.text.Rectangle;
import com.itextpdf.text.pdf.ColumnText;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfPageEventHelper;
import com.itextpdf.text.pdf.PdfTemplate;
import com.itextpdf.text.pdf.PdfWriter;

class Ideone {
	private final Font tinyNormal = new Font(Font.FontFamily.HELVETICA, 9, Font.NORMAL);
	private final Font tinyBold = new Font(Font.FontFamily.HELVETICA, 9, Font.BOLD);

	public static void main(String[] args) throws DocumentException,
			IOException {
		new Factura().createPdf("tableTest.pdf");
	}
	

	public void createPdf(String filename) throws DocumentException, IOException {
		// step 1
		Document document = new Document();
		// step 2
		PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(filename));
		HorizontalPageEventHelper event = new HorizontalPageEventHelper(document, "DATA1", "DATA2");
		writer.setPageEvent(event);
		
		// step 3
		document.open();
		// step 4
		
		PdfPTable tableFactura = new PdfPTable(4);
		tableFactura.setWidthPercentage(80f);
		tableFactura.setWidths(new int[]{55, 15, 15, 15});
		tableFactura.setKeepTogether(false);
		tableFactura.setHeaderRows(1);
		
		PdfPCell cell;
		
		// CABECERA DE LA TABLA
		cell = new PdfPCell();
		cell.setBorder(Rectangle.BOX);
		cell.addElement(new Paragraph("descripcion_titulo", tinyBold));
		cell.setPaddingLeft(10f);
		tableFactura.addCell(cell);
		
		cell = new PdfPCell(new Paragraph("peso_titulo", tinyBold));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBorder(Rectangle.BOX);
		tableFactura.addCell(cell);
		
		cell = new PdfPCell(new Paragraph("precio_titulo", tinyBold));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBorder(Rectangle.BOX);
		tableFactura.addCell(cell);
		
		cell = new PdfPCell(new Paragraph("total_titulo", tinyBold));
		cell.setHorizontalAlignment(Element.ALIGN_CENTER);
		cell.setBorder(Rectangle.BOX);
		tableFactura.addCell(cell);
		
		// marcamos la fila inicial como header
		tableFactura.setHeaderRows(1);
		
		for (int numeroLinea=1;numeroLinea <= 200;numeroLinea++)
		{
			// descripcion 
			cell = new PdfPCell(new Paragraph("1", tinyNormal));
			cell.setHorizontalAlignment(Element.ALIGN_LEFT);
			cell.setPaddingLeft(10f);
			cell.setPaddingTop(5f);
			cell.setBorder(Rectangle.LEFT);
			tableFactura.addCell(cell);
			
			// peso linea
			cell = new PdfPCell(new Paragraph("2", tinyNormal));
			cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			cell.setPaddingRight(10f);
			cell.setPaddingTop(5f);
			cell.setBorder(Rectangle.LEFT);
			tableFactura.addCell(cell);
			
			// precio_linea
			cell = new PdfPCell(new Paragraph("3", tinyNormal));
			cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			cell.setPaddingRight(15f);
			cell.setPaddingTop(5f);
			cell.setBorder(Rectangle.LEFT);
			tableFactura.addCell(cell);
			
			// total linea
			cell = new PdfPCell(new Paragraph("4", tinyNormal));
			cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
			cell.setPaddingRight(10f);
			cell.setPaddingTop(5f);
			cell.setBorder(Rectangle.LEFT | Rectangle.RIGHT);
			tableFactura.addCell(cell);
			
		}
		
		document.add(tableFactura);
		
		// step 5
		document.close();
	}
	
	class HorizontalPageEventHelper extends PdfPageEventHelper {

		/** The template with the total number of pages. */
		PdfTemplate total;
		Document document;
		String numeroDocumento;
		String fechaDocumento;

		
		public HorizontalPageEventHelper(Document document, String numeroDocumento, String fechaDocumento) {
			this.document = document;
			this.numeroDocumento = numeroDocumento;
			this.fechaDocumento = fechaDocumento;
		}
		
		/**
		 * Creates the PdfTemplate that will hold the total number of pages.
		 * 
		 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter,
		 *      com.itextpdf.text.Document)
		 */
		public void onOpenDocument(PdfWriter writer, Document document) {
			total = writer.getDirectContent().createTemplate(16, 16);
		}

		public void onStartPage(PdfWriter writer, Document document) {
		}

		public void onEndPage(PdfWriter writer, Document document) {

			PdfPTable table = new PdfPTable(1);
			PdfPTable fechaPdfPTable = new PdfPTable(2);
			
			table.setTotalWidth(530);
			fechaPdfPTable.setTotalWidth(530);
			
			try {

				fechaPdfPTable.setWidths(new int[] { 96, 7 });
				fechaPdfPTable.setLockedWidth(true);

				// numero de contrato y fecha
				Chunk tituloContrato = new Chunk(numeroDocumento, tinyBold);
				Chunk fechaChunk = new Chunk(fechaDocumento, tinyNormal);
				
				Phrase frase = new Phrase();
				frase.add(tituloContrato);
				frase.add(new Chunk("\n\n"));
				frase.add(fechaChunk);
				
				PdfPCell cell = new PdfPCell(frase);
				cell.setPaddingBottom((float) 0.5);
				cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
				cell.setBorderWidth(0);
				table.addCell(cell);
				
				// numeros de pagina
				Chunk numeracion = new Chunk("Pag:" + String.format(" %d /", writer.getPageNumber()), tinyNormal);
				Phrase fraseFecha = new Phrase();
				fraseFecha.add(numeracion);
				cell = new PdfPCell(fraseFecha);
				cell.setHorizontalAlignment(Element.ALIGN_RIGHT);
				cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
				cell.setPaddingBottom((float) 0.5);
				cell.setBorderWidth(0);
				fechaPdfPTable.addCell(cell);
				
				cell = new PdfPCell(Image.getInstance(total));
				cell.setHorizontalAlignment(Element.ALIGN_LEFT);
				cell.setVerticalAlignment(Element.ALIGN_BOTTOM);
				cell.setBorderWidth(0);
				fechaPdfPTable.addCell(cell);

				// escribimos las lineas
				table.writeSelectedRows(0, -1, 34, 823, writer.getDirectContent());
				fechaPdfPTable.writeSelectedRows(0, -1, 62, 816, writer.getDirectContent());
				
			} catch (DocumentException de) {
				throw new ExceptionConverter(de);
			}
			
		}

		/**
		 * Fills out the total number of pages before the document is closed.
		 * 
		 * @see com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf.text.pdf.PdfWriter, com.itextpdf.text.Document)
		 */
		public void onCloseDocument(PdfWriter writer, Document document) 
		{
			ColumnText.showTextAligned(total, Element.ALIGN_LEFT, new Phrase(String.valueOf(writer.getPageNumber() - 1), tinyNormal), 0, 0.5f, 0);
		}
	}
	
}