1 /** 2 * Licensed under the Artistic License; you may not use this file 3 * except in compliance with the License. 4 * You may obtain a copy of the License at 5 * 6 * http://displaytag.sourceforge.net/license.html 7 * 8 * THIS PACKAGE IS PROVIDED "AS IS" AND WITHOUT ANY EXPRESS OR 9 * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED 10 * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE. 11 */ 12 package org.displaytag.export; 13 14 import java.awt.Color; 15 import java.io.OutputStream; 16 import java.util.Iterator; 17 18 import javax.servlet.jsp.JspException; 19 20 import org.apache.commons.lang.ObjectUtils; 21 import org.apache.commons.lang.StringUtils; 22 import org.displaytag.Messages; 23 import org.displaytag.exception.BaseNestableJspTagException; 24 import org.displaytag.exception.SeverityEnum; 25 import org.displaytag.model.Column; 26 import org.displaytag.model.ColumnIterator; 27 import org.displaytag.model.HeaderCell; 28 import org.displaytag.model.Row; 29 import org.displaytag.model.RowIterator; 30 import org.displaytag.model.TableModel; 31 import org.displaytag.util.TagConstants; 32 33 import com.lowagie.text.BadElementException; 34 import com.lowagie.text.Cell; 35 import com.lowagie.text.Chunk; 36 import com.lowagie.text.Document; 37 import com.lowagie.text.Element; 38 import com.lowagie.text.Font; 39 import com.lowagie.text.FontFactory; 40 import com.lowagie.text.HeaderFooter; 41 import com.lowagie.text.PageSize; 42 import com.lowagie.text.Phrase; 43 import com.lowagie.text.Rectangle; 44 import com.lowagie.text.Table; 45 import com.lowagie.text.pdf.PdfWriter; 46 47 48 /** 49 * PDF exporter using IText. This class is provided more as an example than as a "production ready" class: users 50 * probably will need to write a custom export class with a specific layout. 51 * @author Ivan Markov 52 * @author Fabrizio Giustina 53 * @version $Revision: 1081 $ ($Author: fgiust $) 54 */ 55 public class PdfView implements BinaryExportView 56 { 57 58 /** 59 * TableModel to render. 60 */ 61 private TableModel model; 62 63 /** 64 * export full list? 65 */ 66 private boolean exportFull; 67 68 /** 69 * include header in export? 70 */ 71 private boolean header; 72 73 /** 74 * decorate export? 75 */ 76 private boolean decorated; 77 78 /** 79 * This is the table, added as an Element to the PDF document. It contains all the data, needed to represent the 80 * visible table into the PDF 81 */ 82 private Table tablePDF; 83 84 /** 85 * The default font used in the document. 86 */ 87 private Font smallFont; 88 89 /** 90 * @see org.displaytag.export.ExportView#setParameters(TableModel, boolean, boolean, boolean) 91 */ 92 public void setParameters(TableModel tableModel, boolean exportFullList, boolean includeHeader, 93 boolean decorateValues) 94 { 95 this.model = tableModel; 96 this.exportFull = exportFullList; 97 this.header = includeHeader; 98 this.decorated = decorateValues; 99 } 100 101 /** 102 * Initialize the main info holder table. 103 * @throws BadElementException for errors during table initialization 104 */ 105 protected void initTable() throws BadElementException 106 { 107 tablePDF = new Table(this.model.getNumberOfColumns()); 108 tablePDF.setDefaultVerticalAlignment(Element.ALIGN_TOP); 109 tablePDF.setCellsFitPage(true); 110 tablePDF.setWidth(100); 111 112 tablePDF.setPadding(2); 113 tablePDF.setSpacing(0); 114 115 smallFont = FontFactory.getFont(FontFactory.HELVETICA, 7, Font.NORMAL, new Color(0, 0, 0)); 116 117 } 118 119 /** 120 * @see org.displaytag.export.BaseExportView#getMimeType() 121 * @return "application/pdf" 122 */ 123 public String getMimeType() 124 { 125 return "application/pdf"; //$NON-NLS-1$ 126 } 127 128 /** 129 * The overall PDF table generator. 130 * @throws JspException for errors during value retrieving from the table model 131 * @throws BadElementException IText exception 132 */ 133 protected void generatePDFTable() throws JspException, BadElementException 134 { 135 if (this.header) 136 { 137 generateHeaders(); 138 } 139 tablePDF.endHeaders(); 140 generateRows(); 141 } 142 143 /** 144 * @see org.displaytag.export.BinaryExportView#doExport(OutputStream) 145 */ 146 public void doExport(OutputStream out) throws JspException 147 { 148 try 149 { 150 // Initialize the table with the appropriate number of columns 151 initTable(); 152 153 // Initialize the Document and register it with PdfWriter listener and the OutputStream 154 Document document = new Document(PageSize.A4.rotate(), 60, 60, 40, 40); 155 document.addCreationDate(); 156 HeaderFooter footer = new HeaderFooter(new Phrase(TagConstants.EMPTY_STRING, smallFont), true); 157 footer.setBorder(Rectangle.NO_BORDER); 158 footer.setAlignment(Element.ALIGN_CENTER); 159 160 PdfWriter.getInstance(document, out); 161 162 // Fill the virtual PDF table with the necessary data 163 generatePDFTable(); 164 document.open(); 165 document.setFooter(footer); 166 document.add(this.tablePDF); 167 document.close(); 168 169 } 170 catch (Exception e) 171 { 172 throw new PdfGenerationException(e); 173 } 174 } 175 176 /** 177 * Generates the header cells, which persist on every page of the PDF document. 178 * @throws BadElementException IText exception 179 */ 180 protected void generateHeaders() throws BadElementException 181 { 182 Iterator iterator = this.model.getHeaderCellList().iterator(); 183 184 while (iterator.hasNext()) 185 { 186 HeaderCell headerCell = (HeaderCell) iterator.next(); 187 188 String columnHeader = headerCell.getTitle(); 189 190 if (columnHeader == null) 191 { 192 columnHeader = StringUtils.capitalize(headerCell.getBeanPropertyName()); 193 } 194 195 Cell hdrCell = getCell(columnHeader); 196 hdrCell.setGrayFill(0.9f); 197 hdrCell.setHeader(true); 198 tablePDF.addCell(hdrCell); 199 200 } 201 } 202 203 /** 204 * Generates all the row cells. 205 * @throws JspException for errors during value retrieving from the table model 206 * @throws BadElementException errors while generating content 207 */ 208 protected void generateRows() throws JspException, BadElementException 209 { 210 // get the correct iterator (full or partial list according to the exportFull field) 211 RowIterator rowIterator = this.model.getRowIterator(this.exportFull); 212 // iterator on rows 213 while (rowIterator.hasNext()) 214 { 215 Row row = rowIterator.next(); 216 217 // iterator on columns 218 ColumnIterator columnIterator = row.getColumnIterator(this.model.getHeaderCellList()); 219 220 while (columnIterator.hasNext()) 221 { 222 Column column = columnIterator.nextColumn(); 223 224 // Get the value to be displayed for the column 225 Object value = column.getValue(this.decorated); 226 227 Cell cell = getCell(ObjectUtils.toString(value)); 228 tablePDF.addCell(cell); 229 } 230 } 231 } 232 233 /** 234 * Returns a formatted cell for the given value. 235 * @param value cell value 236 * @return Cell 237 * @throws BadElementException errors while generating content 238 */ 239 private Cell getCell(String value) throws BadElementException 240 { 241 Cell cell = new Cell(new Chunk(StringUtils.trimToEmpty(value), smallFont)); 242 cell.setVerticalAlignment(Element.ALIGN_TOP); 243 cell.setLeading(8); 244 return cell; 245 } 246 247 /** 248 * Wraps IText-generated exceptions. 249 * @author Fabrizio Giustina 250 * @version $Revision: 1081 $ ($Author: fgiust $) 251 */ 252 static class PdfGenerationException extends BaseNestableJspTagException 253 { 254 255 /** 256 * D1597A17A6. 257 */ 258 private static final long serialVersionUID = 899149338534L; 259 260 /** 261 * Instantiate a new PdfGenerationException with a fixed message and the given cause. 262 * @param cause Previous exception 263 */ 264 public PdfGenerationException(Throwable cause) 265 { 266 super(PdfView.class, Messages.getString("PdfView.errorexporting"), cause); //$NON-NLS-1$ 267 } 268 269 /** 270 * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity() 271 */ 272 public SeverityEnum getSeverity() 273 { 274 return SeverityEnum.ERROR; 275 } 276 } 277 }