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: 1.7 $ ($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";
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
151 initTable();
152
153
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
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
211 RowIterator rowIterator = this.model.getRowIterator(this.exportFull);
212
213 while (rowIterator.hasNext())
214 {
215 Row row = rowIterator.next();
216
217
218 ColumnIterator columnIterator = row.getColumnIterator(this.model.getHeaderCellList());
219
220 while (columnIterator.hasNext())
221 {
222 Column column = columnIterator.nextColumn();
223
224
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: 1.7 $ ($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);
267 }
268
269 /***
270 * @see org.displaytag.exception.BaseNestableJspTagException#getSeverity()
271 */
272 public SeverityEnum getSeverity()
273 {
274 return SeverityEnum.ERROR;
275 }
276 }
277 }