View Javadoc

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 }