/* * $Id: ReportPDFWriter.java,v 1.14 2004/03/17 09:10:47 anders Exp $ * * Copyright (C) 2003 Agura IT. All Rights Reserved. * * This software is the proprietary information of Agura IT AB. * Use is subject to license terms. * */ package se.idega.idegaweb.commune.school.report.business; import java.awt.Point; import java.sql.Date; import java.text.NumberFormat; import java.util.StringTokenizer; import javax.ejb.FinderException; import com.idega.core.file.data.ICFile; import com.idega.core.file.data.ICFileBMPBean; import com.idega.core.file.data.ICFileHome; import com.idega.data.IDOLookupException; import com.idega.idegaweb.IWResourceBundle; import com.idega.io.MemoryFileBuffer; import com.idega.io.MemoryInputStream; import com.idega.io.MemoryOutputStream; import com.lowagie.text.BadElementException; import com.lowagie.text.Document; import com.lowagie.text.DocumentException; import com.lowagie.text.Element; import com.lowagie.text.Font; import com.lowagie.text.PageSize; import com.lowagie.text.Phrase; import com.lowagie.text.Table; import com.lowagie.text.pdf.PdfWriter; /** * Creates report files in Adobe PDF format. * <p> * Last modified: $Date: 2004/03/17 09:10:47 $ by $Author: anders $ * * @author Anders Lindman * @version $Revision: 1.14 $ */ public class ReportPDFWriter { private final static String REPORT_FOLDER_NAME = "School Report Files"; private ReportModel _reportModel = null; private IWResourceBundle _iwrb = null; private Font _normalFont = null; private Font _boldFont = null; int _widths[] = null; /** * Constructs a report PDF writer object. * @param reportModel the report model to write as a PDF file * @param iwrb the resource bundle to use for translating text labels */ public ReportPDFWriter(ReportModel reportModel, IWResourceBundle iwrb) { _reportModel = reportModel; _iwrb = iwrb; } /** * Creates the PDF report file. */ public ICFile createFile() { ICFile reportFolder = null; ICFileHome fileHome = null; try { fileHome = (ICFileHome) com.idega.data.IDOLookup.getHome(ICFile.class); reportFolder = fileHome.findByFileName(REPORT_FOLDER_NAME); } catch (FinderException e) { try { ICFile root = fileHome.findByFileName(ICFileBMPBean.IC_ROOT_FOLDER_NAME); reportFolder = fileHome.create(); reportFolder.setName(REPORT_FOLDER_NAME); reportFolder.setMimeType("application/vnd.iw-folder"); reportFolder.store(); root.addChild(reportFolder); } catch (Exception e2) { System.out.println(e2); return null; } } catch (IDOLookupException e) { System.out.println(e); return null; } ICFile exportFile = null; String filename = _reportModel.getReportTitleLocalizationKey() + ".pdf"; try { MemoryFileBuffer buffer = getPDFBuffer(); MemoryInputStream mis = new MemoryInputStream(buffer); try { exportFile = fileHome.findByFileName(filename); if (exportFile != null) { exportFile.remove(); } } catch (FinderException e) {} exportFile = fileHome.create(); exportFile.setFileValue(mis); exportFile.setMimeType("application/pdf"); exportFile.setName(filename); exportFile.setFileSize(buffer.length()); exportFile.store(); reportFolder.addChild(exportFile); } catch (Exception e) { System.out.println(e); } return exportFile; } /* * Returns the memory buffer for the PDF file. */ private MemoryFileBuffer getPDFBuffer() throws DocumentException { MemoryFileBuffer buffer = new MemoryFileBuffer(); MemoryOutputStream mos = new MemoryOutputStream(buffer); Document document = new Document(PageSize.A4, 50, 50, 50, 50); PdfWriter writer = PdfWriter.getInstance(document, mos); String titleKey = _reportModel.getReportTitleLocalizationKey(); String title = localize(titleKey, titleKey); _normalFont = new Font(Font.HELVETICA, 7, Font.NORMAL); _boldFont = new Font(Font.HELVETICA, 7, Font.BOLD); document.addTitle(title); document.addAuthor("Agura IT Reports"); document.addSubject(title); document.open(); String dateString = new Date(System.currentTimeMillis()).toString(); document.add(new Phrase(title + " " + dateString + "\n\n", _boldFont)); document.add(new Phrase("\n", _boldFont)); int cols = _reportModel.getColumnSize() + 1; Table table = new Table(cols); _widths = new int[cols]; for (int i = 0; i < cols; i++) { _widths[i] = 1; } table.setSpacing(1.5f); buildColumnHeaders(table); buildRowHeaders(table); buildReportCells(table); int totalWidth = 0; for (int i = 0; i < cols; i++) { _widths[i] += 1; totalWidth += _widths[i]; } int width = (100 * totalWidth) / 95; if (width > 100) { width = 100; } table.setWidth(width); table.setWidths(_widths); document.add(table); document.close(); writer.setPdfVersion(PdfWriter.VERSION_1_2); return buffer; } /** * Builds the report column headers. */ protected void buildColumnHeaders(Table table) throws BadElementException { Header[] headers = _reportModel.getColumnHeaders(); com.lowagie.text.Cell cell = new com.lowagie.text.Cell(); cell.setRowspan(2); table.addCell(cell, new Point(0, 0)); int column = 1; for (int i = 0; i < headers.length; i++) { Header header = headers[i]; Header[] children = header.getChildren(); if (children == null) { String s = null; if (header.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) { s = header.getLocalizationKey(); } else { s = localize(header.getLocalizationKey(), header.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _normalFont)); cell.setRowspan(2); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_BOTTOM); table.addCell(cell, new Point(0, column)); setColSize(s, column, true); column++; } else { String s = null; if (header.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) { s = header.getLocalizationKey(); } else { s = localize(header.getLocalizationKey(), header.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _normalFont)); cell.setColspan(children.length); cell.setHorizontalAlignment(Element.ALIGN_CENTER); table.addCell(cell, new Point(0, column)); if (children.length == 1) { setColSize(s, column, false); } for (int j = 0; j < children.length; j++) { Header child = children[j]; s = null; if (child.getHeaderType() == Header.HEADERTYPE_COLUMN_NONLOCALIZED_HEADER) { s = child.getLocalizationKey(); } else { s = localize(child.getLocalizationKey(), child.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _normalFont)); cell.setHorizontalAlignment(Element.ALIGN_CENTER); cell.setVerticalAlignment(Element.ALIGN_BOTTOM); cell.setNoWrap(true); table.addCell(cell, new Point(1, column + j)); setColSize(s, column + j, false); } column += children.length; } } } /** * Builds the report row headers. */ protected void buildRowHeaders(Table table) throws BadElementException { Header[] headers = _reportModel.getRowHeaders(); int row = 2; String s = null; com.lowagie.text.Cell cell = null; for (int i = 0; i < headers.length; i++) { Header header = headers[i]; Header[] children = header.getChildren(); if (children == null) { int headerType = header.getHeaderType(); if (headerType == Header.HEADERTYPE_ROW_SPACER) { s = " "; } else if (headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER || header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) { s = header.getLocalizationKey(); } else { s = localize(header.getLocalizationKey(), header.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _boldFont)); if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) { cell.setColspan(_reportModel.getColumnSize() + 1); } cell.setNoWrap(true); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); if (headerType == Header.HEADERTYPE_ROW_LABEL) { cell.setBackgroundColor(new java.awt.Color(0xe0, 0xe0, 0xe0)); } table.addCell(cell, new Point(row, 0)); setColSize(s, 0, false); row++; } else { if (header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER || header.getHeaderType() == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) { s = header.getLocalizationKey(); } else { s = localize(header.getLocalizationKey(), header.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _normalFont)); cell.setColspan(_reportModel.getColumnSize() + 1); cell.setLeading(16); table.addCell(cell, new Point(row, 0)); row++; for (int j = 0; j < children.length; j++) { Header child = children[j]; int headerType = child.getHeaderType(); if (headerType == Header.HEADERTYPE_ROW_SPACER) { s = " "; } else if (headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_HEADER || headerType == Header.HEADERTYPE_ROW_NONLOCALIZED_NORMAL) { s = child.getLocalizationKey(); } else { s = localize(child.getLocalizationKey(), child.getLocalizationKey()); } cell = new com.lowagie.text.Cell(new Phrase(s, _boldFont)); if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) { cell.setColspan(_reportModel.getColumnSize() + 1); } cell.setNoWrap(true); cell.setVerticalAlignment(Element.ALIGN_MIDDLE); if (headerType == Header.HEADERTYPE_ROW_LABEL) { cell.setBackgroundColor(new java.awt.Color(0xe0, 0xe0, 0xe0)); } table.addCell(cell, row, 0); setColSize(s, 0, false); row++; } } } } /** * Builds the report cells. */ protected void buildReportCells(Table table) throws BadElementException { int cellRow = 0; int tableRow = 2; Header[] rowHeaders = _reportModel.getRowHeaders(); NumberFormat formatter = NumberFormat.getNumberInstance(); formatter.setMaximumFractionDigits(1); for (int i = 0; i < rowHeaders.length; i++) { int rowCount = 0; Header header = rowHeaders[i]; Header[] children = header.getChildren(); boolean hasChildren = false; if (children != null) { hasChildren = true; tableRow++; rowCount = children.length; } else { int headerType = header.getHeaderType(); if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) { rowCount = 0; tableRow++; } else { rowCount = 1; } } for (int j = 0; j < rowCount; j++) { if (hasChildren) { Header child = children[j]; int headerType = child.getHeaderType(); if (headerType == Header.HEADERTYPE_ROW_LABEL || headerType == Header.HEADERTYPE_ROW_SPACER) { tableRow++; continue; } } for (int cellColumn = 0; cellColumn < _reportModel.getColumnSize(); cellColumn++) { Cell cell = _reportModel.getCell(cellRow, cellColumn); int align = Element.ALIGN_RIGHT; Font font = _normalFont; String s = null; switch (cell.getCellType()) { case Cell.CELLTYPE_PERCENT: s = formatter.format(cell.getFloatValue()); break; case Cell.CELLTYPE_ROW_HEADER: s = cell.getStringValue(); if (s.equals(" ")) { s = " "; } font = _boldFont; align = Element.ALIGN_LEFT; break; case Cell.CELLTYPE_SUM: s = formatNumber(cell.getValue()); font = _boldFont; break; case Cell.CELLTYPE_TOTAL: s = formatNumber(cell.getValue()); font = _boldFont; break; default: s = formatNumber(cell.getValue()); break; } int tableColumn = cellColumn + 1; com.lowagie.text.Cell pdfCell = new com.lowagie.text.Cell(new Phrase(s, font)); pdfCell.setHorizontalAlignment(align); pdfCell.setNoWrap(true); pdfCell.setVerticalAlignment(Element.ALIGN_MIDDLE); table.addCell(pdfCell, new Point(tableRow, tableColumn)); setColSize(s, tableColumn, false); } cellRow++; tableRow++; } } _reportModel.close(); } /* * Sets a column size. */ private void setColSize(String text, int column, boolean wrap) { String s = ""; if (wrap) { StringTokenizer st = new StringTokenizer(text, " "); while (st.hasMoreTokens()) { String token = st.nextToken(); int tlen = token.length(); if (tlen > s.length()) { s = token; } } } else { s = text; } int len = s.length(); if (_widths[column] < len) { if (s.indexOf('m') != -1) { len++; } _widths[column] = len; } } /* * Returns a string with space for numbers larger than 999. */ String formatNumber(int n) { if (n == 0) { return " "; } String s = "" + n; int length = s.length(); if (length > 3) { s = s.substring(0, (length - 3)) + " " + s.substring(length - 3); } return s; } /* * Returns the localized text for the specified key. */ private String localize(String key, String defaultText) { return _iwrb.getLocalizedString(key, defaultText); } }