Java tutorial
/* * This file is part of the aidGer project. * * Copyright (C) 2010-2013 The aidGer Team * * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. */ /** * */ package de.aidger.utils.pdf; import static de.aidger.utils.Translation._; import java.awt.Desktop; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.FileOutputStream; import java.io.IOException; import java.net.URL; import java.util.Calendar; import java.util.List; import com.itextpdf.text.Document; import com.itextpdf.text.DocumentException; import com.itextpdf.text.Element; import com.itextpdf.text.Font; import com.itextpdf.text.Image; import com.itextpdf.text.PageSize; import com.itextpdf.text.Phrase; import com.itextpdf.text.Rectangle; import com.itextpdf.text.pdf.BaseFont; import com.itextpdf.text.pdf.ColumnText; import com.itextpdf.text.pdf.PdfContentByte; import com.itextpdf.text.pdf.PdfImportedPage; import com.itextpdf.text.pdf.PdfPCell; import com.itextpdf.text.pdf.PdfPTable; import com.itextpdf.text.pdf.PdfPageEventHelper; import com.itextpdf.text.pdf.PdfReader; import com.itextpdf.text.pdf.PdfTemplate; import com.itextpdf.text.pdf.PdfWriter; import de.aidger.model.Runtime; import de.aidger.model.models.Activity; import de.aidger.model.reports.ProtocolCreator; import de.aidger.utils.DateUtils; import de.aidger.view.UI; /** * This class converts protocols to a format for iText and exports it to a .pdf * file. * * @author aidGer Team */ public class ProtocolConverter { /** * The PDF-document which will be created. */ private Document document = null; /** * The PdfWriter used to write the document. */ private PdfWriter writer = null; /** * The number of days before the current one to display activities of. */ private int numberOfDays = 0; /** * Whether the file was created successfully. */ private boolean fileCreated = false; /** * The name of this report. */ private static String name; /** * Initializes a new ProtocolConverter and creates the .pdf file. * * @param file * The filepath of the file. * @param numberOfDays * The number of days to display activities of. */ public ProtocolConverter(File file, int numberOfDays) { this.numberOfDays = numberOfDays; document = new Document(PageSize.A4.rotate()); document.setMargins(document.leftMargin(), document.rightMargin(), document.topMargin() + 25, document.bottomMargin()); file = checkExtension(file); name = _("Activity Protocol"); File preTemplateFile = null; try { preTemplateFile = File.createTempFile("BudgetReport", ".pdf"); } catch (IOException e2) { e2.printStackTrace(); } makeNewDocument(preTemplateFile); if (fileCreated) { /* * If there were no problems creating the file, go on and add * content to it. Do nothing otherwise. */ writeTable(); addActivities(); document.close(); applyTemplate(file, preTemplateFile); preTemplateFile.delete(); /* * Open the created document if the setting is enabled with the * specified pdf viewer. */ if (Runtime.getInstance().getOption("auto-open").equals("true")) { try { java.lang.Runtime.getRuntime().exec( new String[] { Runtime.getInstance().getOption("pdf-viewer"), file.getAbsolutePath() }); } catch (IOException e) { try { Desktop.getDesktop().open(file); } catch (IOException e1) { UI.displayError(_("No pdf viewer could be found!")); } } } } } /** * Initializes a new protocol converter that creates a pdf with a given list * of activities. * * @param file * The file path and name of the pdf. * @param activities * The list of activities to be exported. */ public ProtocolConverter(File file, List<Activity> activities) { document = new Document(PageSize.A4.rotate()); document.setMargins(document.leftMargin(), document.rightMargin(), document.topMargin() + 25, document.bottomMargin()); file = checkExtension(file); name = _("Activity Protocol"); File preTemplateFile = null; try { preTemplateFile = File.createTempFile("BudgetReport", ".pdf"); } catch (IOException e2) { e2.printStackTrace(); } makeNewDocument(preTemplateFile); if (fileCreated) { /* * If there were no problems creating the file, go on and add * content to it. Do nothing otherwise. */ writeTable(); try { /* * Add an activity row to the table for every activity in the * list. */ PdfPTable contentTable = new PdfPTable(1); for (Activity activity : activities) { PdfPCell cell; cell = new PdfPCell(addRow(new ProtocolCreator().getObjectArray(activity))); cell.setBorder(0); contentTable.addCell(cell); } document.add(contentTable); } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } document.close(); if (applyTemplate(file, preTemplateFile)) { preTemplateFile.delete(); /* * Open the created document if the setting is enabled with the * specified pdf viewer. */ if (Runtime.getInstance().getOption("auto-open").equals("true")) { try { java.lang.Runtime.getRuntime().exec(new String[] { Runtime.getInstance().getOption("pdf-viewer"), file.getAbsolutePath() }); } catch (IOException e) { try { Desktop.getDesktop().open(file); } catch (IOException e1) { UI.displayError(_("No pdf viewer could be found!")); } } } } else { preTemplateFile.delete(); } } } /** * Checks if the extension of the file is in fact .pdf. If not, it adds the * .pdf extension to the file name. * * @param file * The file to check. * @return The file name with the correct extension. */ private File checkExtension(File file) { String fileName = file.getName(); int fileExtensionStart = fileName.lastIndexOf('.'); String fileExtension = fileName.substring(fileExtensionStart + 1); if (!fileExtension.equals("pdf")) { return new File(file.getPath() + ".pdf"); } return file; } /** * Places the created document onto the template for this report. * * @param file * The file to which this report will be saved. * @param preTemplateFile * The report to be used. */ private boolean applyTemplate(File file, File preTemplateFile) { FileOutputStream outStream = null; FileInputStream inStream = null; PdfContentByte contentByte = null; PdfReader reader = null, templateReader = null; try { /* * Use the template located in the configuration path first, if it * exists. */ File template = new File(Runtime.getInstance().getConfigPath() + "/templates/ProtocolTemplate.pdf"); URL templateURL = null; if (template.exists()) { templateURL = template.toURI().toURL(); } else { templateURL = getClass().getResource("/de/aidger/res/pdf/ProtocolTemplate.pdf"); } if (templateURL == null) { throw new FileNotFoundException(_("The report template could not be loaded.") + " " + _("Please make sure that a fitting template exists in the template folder.")); } Document document = new Document(PageSize.A4.rotate()); outStream = new FileOutputStream(file.getPath()); inStream = new FileInputStream(preTemplateFile); writer = PdfWriter.getInstance(document, outStream); document.open(); contentByte = writer.getDirectContent(); reader = new PdfReader(inStream); templateReader = new PdfReader(templateURL); /* * Add the template pdf to the document and place the finished * report on top of it. */ for (int i = 1; i <= reader.getNumberOfPages(); i++) { document.newPage(); PdfImportedPage page = writer.getImportedPage(templateReader, 1); int rotation = templateReader.getPageRotation(1); if (rotation == 90 || rotation == 270) { //landscape mode contentByte.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(1).getHeight()); } else { //portrait mode contentByte.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } page = writer.getImportedPage(reader, i); rotation = reader.getPageRotation(i); if (rotation == 90 || rotation == 270) { //landscape mode contentByte.addTemplate(page, 0, -1f, 1f, 0, 0, reader.getPageSizeWithRotation(1).getHeight()); } else { //portrait mode contentByte.addTemplate(page, 1f, 0, 0, 1f, 0, 0); } } document.close(); return true; } catch (FileNotFoundException e) { if (e.getMessage() != null) { UI.displayError(e.getMessage()); } } catch (DocumentException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } return false; } /** * Creates a new document. * * @param file * The file to create. */ private void makeNewDocument(File file) { FileOutputStream outStream = null; try { outStream = new FileOutputStream(file.getPath()); writer = PdfWriter.getInstance(document, outStream); HeaderFooter event = new HeaderFooter(); writer.setPageEvent(event); document.open(); fileCreated = true; } catch (FileNotFoundException e1) { UI.displayError(_("File could not be created.") + " " + _("Please close all processes that are using the file.")); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * This class is used to write the headers and footers of every page. * * @author aidGer Team */ static class HeaderFooter extends PdfPageEventHelper { /** * The template containing the total number of pages. */ PdfTemplate total; /* * (non-Javadoc) * * @see * com.itextpdf.text.pdf.PdfPageEventHelper#onOpenDocument(com.itextpdf * .text.pdf.PdfWriter, com.itextpdf.text.Document) */ @Override public void onOpenDocument(PdfWriter writer, Document document) { total = writer.getDirectContent().createTemplate(30, 16); } /* * (non-Javadoc) * * @see * com.itextpdf.text.pdf.PdfPageEventHelper#onStartPage(com.itextpdf * .text.pdf.PdfWriter, com.itextpdf.text.Document) */ @Override public void onStartPage(PdfWriter writer, Document document) { PdfPTable table = new PdfPTable(3); table.setTotalWidth(writer.getPageSize().getRight() - document.rightMargin() - document.leftMargin()); try { Font pageTitleFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 18); Font authorNameFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 8); PdfPCell left = new PdfPCell(); PdfPCell center; if (writer.getCurrentPageNumber() == 1) { center = new PdfPCell(new Phrase(name, pageTitleFont)); } else { center = new PdfPCell(new Phrase("")); } center.setHorizontalAlignment(Element.ALIGN_CENTER); center.setVerticalAlignment(Element.ALIGN_BOTTOM); center.setBorder(Rectangle.BOTTOM); PdfPCell right = new PdfPCell( new Phrase(_("Author") + ": " + Runtime.getInstance().getOption("name"), authorNameFont)); right.setVerticalAlignment(Element.ALIGN_BOTTOM); right.setHorizontalAlignment(Element.ALIGN_RIGHT); right.setBorder(Rectangle.BOTTOM); left.setBorder(0); center.setBorder(0); right.setBorder(0); left.setPaddingBottom(10); center.setPaddingBottom(10); right.setPaddingBottom(10); table.addCell(left); table.addCell(center); table.addCell(right); table.writeSelectedRows(0, -1, document.leftMargin(), document.getPageSize().getTop() - 15, writer.getDirectContent()); } catch (DocumentException e1) { } catch (IOException e1) { // TODO Auto-generated catch block e1.printStackTrace(); } } /* * (non-Javadoc) * * @see * com.itextpdf.text.pdf.PdfPageEventHelper#onEndPage(com.itextpdf.text * .pdf.PdfWriter, com.itextpdf.text.Document) */ @Override public void onEndPage(PdfWriter writer, Document document) { PdfPTable table = new PdfPTable(3); try { Font pageFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 12); Font generatedByFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 8); table.setWidths(new int[] { 20, 28, 2 }); table.setTotalWidth( writer.getPageSize().getRight() - document.rightMargin() - document.leftMargin()); table.setLockedWidth(true); table.getDefaultCell().setBorder(Rectangle.BOTTOM); table.getDefaultCell().setFixedHeight(20); table.getDefaultCell().setHorizontalAlignment(Element.ALIGN_RIGHT); Calendar calendar = Calendar.getInstance(); PdfPCell dateCell = new PdfPCell(new Phrase(DateUtils.formatDate(calendar.getTime()))); dateCell.setHorizontalAlignment(Element.ALIGN_LEFT); dateCell.setBorder(Rectangle.BOTTOM); table.addCell(dateCell); table.addCell(new Phrase(_("Page") + ": " + writer.getCurrentPageNumber() + " " + _("of") + " ", pageFont)); PdfPCell cell = new PdfPCell(Image.getInstance(total)); cell.setBorder(Rectangle.BOTTOM); table.addCell(cell); table.writeSelectedRows(0, -1, document.leftMargin(), 50, writer.getDirectContent()); Image aidger = Image.getInstance(getClass().getResource("/de/aidger/res/pdf/AidgerLogo.png")); aidger.scaleAbsolute(80.0f, 20.0f); table = new PdfPTable(2); table.setTotalWidth( writer.getPageSize().getRight() - document.rightMargin() - document.leftMargin()); cell = new PdfPCell(new Phrase(_("Generated by: "), generatedByFont)); cell.setBorder(0); cell.setHorizontalAlignment(Element.ALIGN_RIGHT); cell.setPaddingBottom(5); cell.setVerticalAlignment(Element.ALIGN_BOTTOM); table.addCell(cell); cell = new PdfPCell(Image.getInstance(aidger)); cell.setHorizontalAlignment(Element.ALIGN_LEFT); cell.setBorder(0); table.addCell(cell); table.writeSelectedRows(0, -1, document.leftMargin(), 25, writer.getDirectContent()); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /* * (non-Javadoc) * * @see * com.itextpdf.text.pdf.PdfPageEventHelper#onCloseDocument(com.itextpdf * .text.pdf.PdfWriter, com.itextpdf.text.Document) */ @Override public void onCloseDocument(PdfWriter writer, Document document) { try { Font pageFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 12); ColumnText.showTextAligned(total, Element.ALIGN_LEFT, new Phrase(String.valueOf(writer.getPageNumber() - 1), pageFont), 2, 2, 0); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } } /** * Writes the Table of activities. */ private void writeTable() { try { Font tableTitleFont = new Font( BaseFont.createFont(BaseFont.HELVETICA_BOLD, BaseFont.CP1252, BaseFont.EMBEDDED), 9); String[] courseTitles = { _("Affected assistant"), _("Affected course"), _("Type"), _("Date"), _("Content"), _("Initiator"), _("Processor"), _("Remark") }; PdfPTable contentTable = new PdfPTable(1); PdfPTable titleTable = new PdfPTable(8); /* * Create the titles of the table entries. */ for (int i = 0; i < courseTitles.length; i++) { PdfPCell cell = new PdfPCell(new Phrase(courseTitles[i], tableTitleFont)); if (i != 0) { cell.setBorder(6); } else { cell.setBorder(2); } titleTable.addCell(cell); } PdfPCell cell = new PdfPCell(titleTable); cell.setPaddingTop(10.0f); cell.setBorder(0); contentTable.addCell(cell); document.add(contentTable); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Adds activities to the activity table. */ private void addActivities() { try { PdfPTable contentTable = new PdfPTable(1); List<Object[]> activities = new ProtocolCreator().createProtocol(numberOfDays); for (Object activity : activities) { PdfPCell cell = new PdfPCell(addRow((Object[]) activity)); cell.setBorder(0); contentTable.addCell(cell); } document.add(contentTable); } catch (DocumentException e) { // TODO Auto-generated catch block e.printStackTrace(); } catch (IOException e) { // TODO Auto-generated catch block e.printStackTrace(); } } /** * Adds one activity to the activity table. * * @param activity * The activity to add. * @return The PdfPTable of the row. * @throws DocumentException * @throws IOException */ private PdfPTable addRow(Object[] activity) throws DocumentException, IOException { Font tableContentFont = new Font( BaseFont.createFont(BaseFont.HELVETICA, BaseFont.CP1252, BaseFont.EMBEDDED), 9); PdfPTable contentTable = new PdfPTable(8); for (int i = 0; i < 8; i++) { PdfPCell cell = new PdfPCell(new Phrase(activity[i].toString(), tableContentFont)); if (i != 0) { cell.setBorder(4 + Rectangle.TOP); } else { cell.setBorder(0 + Rectangle.TOP); } cell.setPaddingBottom(5); contentTable.addCell(cell); } return contentTable; } }