Java tutorial
package de.dhbw.humbuch.util; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.InputStream; import java.text.SimpleDateFormat; import java.util.Calendar; import java.util.Locale; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.FontFactory; import com.lowagie.text.Image; import com.lowagie.text.Paragraph; import com.lowagie.text.Phrase; import com.lowagie.text.Rectangle; import com.lowagie.text.RectangleReadOnly; import com.lowagie.text.pdf.ColumnText; import com.lowagie.text.pdf.PdfPCell; import com.lowagie.text.pdf.PdfPTable; import com.lowagie.text.pdf.PdfPageEventHelper; import com.lowagie.text.pdf.PdfWriter; import com.vaadin.server.StreamResource.StreamSource; /** * Abstract super class for PDF creation. Determines general layout of PDFs. * @author Benjamin Rthlein * */ public abstract class PDFHandler { private Document document; private HeaderFooter event; protected final static float TABLEWIDTH = 460f; protected final static float CELL_PADDING = 7f; /** * * @param path * links to the directory where the PDF file should be saved */ public PDFHandler(String path) { this.document = new Document(); } /** * Create a document with the specified sizes and margins. This document is the internal representation * of the PDF. */ public PDFHandler() { this.document = new Document(new RectangleReadOnly(595, 842), 30f, 30f, 25f, 35f); } /** * Creates the pdf with the information in the object that was passed to the * constructor previously. * * @param path * where the file will be saved */ public void savePDF(String path) { try { PdfWriter writer = PdfWriter.getInstance(document, new FileOutputStream(path)); event = new HeaderFooter(); writer.setBoxSize("art", new Rectangle(36, 54, 559, 788)); writer.setPageEvent(event); } catch (FileNotFoundException e) { e.printStackTrace(); } catch (DocumentException e) { e.printStackTrace(); } this.document.open(); this.addMetaData(document); this.insertDocumentParts(document); this.document.close(); } /** * Creates a ByteArrayOutputStream which contains the PDF as a byte array. * * @return the byteArrayOutputStream the PDF is stored in, null if an error * occurred. */ public ByteArrayOutputStream createByteArrayOutputStreamForPDF() { ByteArrayOutputStream byteArrayOutputStream; try { byteArrayOutputStream = new ByteArrayOutputStream(); PdfWriter writer = PdfWriter.getInstance(document, byteArrayOutputStream); event = new HeaderFooter(); writer.setBoxSize("art", new Rectangle(36, 54, 559, 788)); writer.setPageEvent(event); this.document.open(); this.addMetaData(document); int initialDocumentSize = writer.getCurrentDocumentSize(); this.insertDocumentParts(document); if (byteArrayOutputStream.size() > 0 || writer.getCurrentDocumentSize() > initialDocumentSize) { this.document.close(); } else { return null; } return byteArrayOutputStream; } catch (DocumentException e) { System.err.println("Could not create ByteArrayOutputStream of PDF data. " + e.getMessage()); } return null; } /** * Adds meta data to the PDF document. The information of using iText must * be part of the meta data due to the license of the iText library! * * @param document * represents the PDF before it is saved */ private void addMetaData(Document document) { document.addTitle("Humbuch Schule"); document.addSubject("Using iText"); document.addKeywords("Java, PDF, iText"); document.addAuthor("Schlager"); document.addCreator("Schlager"); } /** * Set the logo of Humboldt on the left corner and the current date on the * right corner * * @param document * reference of the pdfDocument object */ protected void addHeading(Document document) { Paragraph paragraph = new Paragraph(); PdfPTable table = createMyStandardTable(2); table.setTotalWidth(TABLEWIDTH); PdfPCell cell; Image img = new ResourceLoader("pdf/humboldt_logo.png").getImage(); img.setAlignment(Element.ALIGN_BOTTOM); img.scaleToFit(205f, 65f); cell = new PdfPCell(img); cell.setBorder(0); table.addCell(cell); String date = new SimpleDateFormat("dd.MM.yyyy", Locale.GERMAN).format(Calendar.getInstance().getTime()); cell = new PdfPCell(new Phrase(date)); cell.setBorder(0); cell.setHorizontalAlignment(Element.ALIGN_RIGHT); cell.setVerticalAlignment(Element.ALIGN_BOTTOM); table.addCell(cell); cell = new PdfPCell(new Phrase("")); cell.setBorder(Rectangle.BOTTOM); table.addCell(cell); cell = new PdfPCell(new Phrase("")); cell.setBorder(Rectangle.BOTTOM); table.addCell(cell); paragraph.add(table); addEmptyLine(paragraph, 1); try { document.add(paragraph); } catch (DocumentException e) { e.printStackTrace(); } } /** * Adds a signature field with a date field to the document. Should be the * last part that is added to the document. * * @param document * represents the PDF before it is saved * @param role * word for the kind of person that shall sign the paper */ protected void addSignatureField(Document document, String role) { Paragraph paragraph = new Paragraph(); //this table contains the signatureTable and the dataTable. // this purpose makes it easier to format PdfPTable table = createMyStandardTable(2); //the first column is double times greater than the second column try { table.setWidths(new float[] { 10f, 20f }); } catch (DocumentException e) { e.printStackTrace(); } //create and fill date table PdfPTable dateTable = new PdfPTable(1); PdfPCell cell = new PdfPCell(new Phrase("")); //just the bottom border will be displayed (line for date) cell.setBorderWidthTop(0); cell.setBorderWidthLeft(0); cell.setBorderWidthRight(0); dateTable.addCell(cell); cell = new PdfPCell(new Phrase("Datum")); cell.setBorder(0); dateTable.addCell(cell); //put date table into the 'parent' table cell = new PdfPCell(dateTable); cell.setBorder(0); table.addCell(cell); //create and fill signature table PdfPTable signatureTable = new PdfPTable(1); cell = new PdfPCell(new Phrase("")); //just the bottom border will be displayed (line for signature) cell.setBorderWidthTop(0); cell.setBorderWidthLeft(0); cell.setBorderWidthRight(0); signatureTable.addCell(cell); cell = new PdfPCell(new Phrase("Unterschrift " + role)); cell.setBorder(0); signatureTable.addCell(cell); //put signature table into the 'parent' table cell = new PdfPCell(signatureTable); cell.setBorder(0); table.addCell(cell); paragraph.add(table); try { document.add(paragraph); } catch (DocumentException e) { e.printStackTrace(); } } /** * A table is generated with the header: Klasse, Bezeichnung Lehrmittel, Unterschrift * * @return PdfPTable */ protected PdfPTable createTableWithRentalInformationHeader() { PdfPTable table = createMyStandardTable(3, new float[] { 2.25f, 1f, 1f }); Font font = FontFactory.getFont("Helvetica", 12, Font.BOLD); new PDFHandler.TableBuilder(table, new String[] { "Bezeichnung Lehrmittel", "bis Klasse", "Unterschrift" }) .withBorder(true).isCenterAligned(true).font(font).padding(CELL_PADDING).fillTable(); return table; } /** * A table is generated with the header: Klasse, Bezeichnung Lehrmittel * * @return PdfPTable */ protected PdfPTable createTableWithRentalInformationHeaderWithoutSignColumn() { PdfPTable table = createMyStandardTable(2, new float[] { 3f, 1f }); Font font = FontFactory.getFont("Helvetica", 12, Font.BOLD); new PDFHandler.TableBuilder(table, new String[] { "Bezeichnung Lehrmittel", "bis Klasse" }).withBorder(true) .isCenterAligned(true).font(font).padding(CELL_PADDING).fillTable(); return table; } /** * A table is generated with the header: Bezeichnung Lehrmittel, Anzahl * * @return PdfPTable */ protected PdfPTable createTableWithRentalInformationHeaderForClass() { PdfPTable table = createMyStandardTable(2, new float[] { 3f, 1f }); Font font = FontFactory.getFont("Helvetica", 12, Font.BOLD); new PDFHandler.TableBuilder(table, new String[] { "Bezeichnung Lehrmittel", "Anzahl" }).withBorder(true) .font(font).isCenterAligned(true).padding(CELL_PADDING).fillTable(); return table; } protected void addInformationAboutDocument(Document document, String informationText) { PdfPTable table = createMyStandardTable(1); new PDFHandler.TableBuilder(table, new String[] { informationText }) .font(FontFactory.getFont("Times New Roman", 14, Font.BOLD)).fillTable(); try { document.add(table); PDFHandler.addEmptyLineToDocument(document, 1); } catch (DocumentException e) { e.printStackTrace(); } } protected void resetPageNumber() { this.event.resetPageNumber(); } protected static void addEmptyLine(Paragraph paragraph, int number) { for (int i = 0; i < number; i++) { paragraph.add(new Paragraph(" ")); } } protected static void addEmptyLineToDocument(Document document, int number) { Paragraph paragraph = new Paragraph(); for (int i = 0; i < number; i++) { paragraph.add(new Paragraph(" ")); } try { document.add(paragraph); } catch (DocumentException e) { System.err.println("Could not add empty line to documnet " + e.getStackTrace()); } } /** * Create a standard table with constant table width. * * @param columnNumber * set how many columns the table will have * @return table */ protected static PdfPTable createMyStandardTable(int columnNumber) { PdfPTable table = new PdfPTable(columnNumber); table.setLockedWidth(true); table.setTotalWidth(TABLEWIDTH); return table; } /** * Create a standard table with constant table width. * * @param columnNumber * set how many columns the table will have * @param columnWidths * set the ratio between the columns. If null, all columns will * be equal. * @return table */ protected static PdfPTable createMyStandardTable(int columnNumber, float[] columnWidths) { PdfPTable table = new PdfPTable(columnNumber); table.setLockedWidth(true); table.setTotalWidth(TABLEWIDTH); if (!(columnWidths == null) && (columnWidths.length != 0)) { try { table.setWidths(columnWidths); } catch (DocumentException e) { System.err.println("Could not set columnWidths of standardTable " + e.getStackTrace()); } } return table; } /** * Use the configuration information to fill the table cells * @param tableBuilder Table configuration */ private static void fillTableWithContent(TableBuilder tableBuilder) { PdfPCell cell = null; for (int i = 0; i < tableBuilder.contentArray.length; i++) { if (tableBuilder.contentArray[i] == null || tableBuilder.contentArray[i].equals("null")) { tableBuilder.contentArray[i] = ""; } if (tableBuilder.font != null) { cell = new PdfPCell(new Phrase(tableBuilder.contentArray[i], tableBuilder.font)); } else { cell = new PdfPCell(new Phrase(tableBuilder.contentArray[i])); } if (tableBuilder.isAlignedCentrally) { cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); } if (!tableBuilder.withBorder) { cell.setBorder(0); } if (tableBuilder.padding != 0f) { cell.setPadding(tableBuilder.padding); } if (tableBuilder.leading != 0f) { cell.setLeading(tableBuilder.leading, tableBuilder.leading); } tableBuilder.table.addCell(cell); } } /** * In this method all parts of the document shall be 'put' together. * * @param document * represents the PDF before it is saved */ protected abstract void insertDocumentParts(Document document); /** * In this method the PDF-specific information shall be inserted into the * document. * * @param document * represents the PDF before it is saved */ protected abstract void addContent(Document document); class TableBuilder { private PdfPTable table; private String[] contentArray; private boolean withBorder; private boolean isAlignedCentrally; private float padding; private Font font; private float leading; public TableBuilder(PdfPTable table, String[] contentArray) { this.table = table; this.contentArray = contentArray; } public TableBuilder withBorder(boolean withBorder) { this.withBorder = withBorder; return this; } public TableBuilder isCenterAligned(boolean isCenterAligned) { this.isAlignedCentrally = isCenterAligned; return this; } public TableBuilder padding(float padding) { this.padding = padding; return this; } public TableBuilder font(Font font) { this.font = font; return this; } public TableBuilder leading(float leading) { this.leading = leading; return this; } public void fillTable() { PDFHandler.fillTableWithContent(this); } } /** Inner class to add a header and a footer. */ class HeaderFooter extends PdfPageEventHelper { /** Alternating phrase for the header. */ Phrase[] header = new Phrase[2]; /** Current page number (will be reset for every chapter). */ int pagenumber; /** * Initialize one of the headers. * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onOpenDocument(PdfWriter writer, Document document) { header[0] = new Phrase("Movie history"); } /** * Initialize one of the headers, based on the chapter title; reset the * page number. * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onChapter(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document, float, com.itextpdf.text.Paragraph) */ public void onChapter(PdfWriter writer, Document document, float paragraphPosition, Paragraph title) { header[1] = new Phrase(title.getContent()); pagenumber = 1; } /** * Increase the page number. * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onStartPage(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onStartPage(PdfWriter writer, Document document) { pagenumber++; } /** * Adds the header and the footer. * * @see com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text.pdf.PdfWriter, * com.itextpdf.text.Document) */ public void onEndPage(PdfWriter writer, Document document) { Rectangle rect = writer.getBoxSize("art"); // switch(writer.getPageNumber() % 2) { // case 0: // ColumnText.showTextAligned(writer.getDirectContent(), // Element.ALIGN_RIGHT, header[0], // rect.getRight(), rect.getTop(), 0); // break; // case 1: // ColumnText.showTextAligned(writer.getDirectContent(), // Element.ALIGN_LEFT, header[0], // rect.getLeft(), rect.getTop(), 0); // break; // } ColumnText.showTextAligned(writer.getDirectContent(), Element.ALIGN_CENTER, new Phrase(String.format("- Seite %d -", pagenumber)), (rect.getLeft() + rect.getRight()) / 2, 20, 0); } public void resetPageNumber() { this.pagenumber = 1; } } public static class PDFStreamSource implements StreamSource { private static final long serialVersionUID = 1L; ByteArrayOutputStream byteArrayOutputstream; public PDFStreamSource(ByteArrayOutputStream byteArrayOutputStream) { this.byteArrayOutputstream = byteArrayOutputStream; } @Override public InputStream getStream() { // Here we return the pdf contents as a byte-array return new ByteArrayInputStream(this.byteArrayOutputstream.toByteArray()); } } }