001: /* Jasperreport.java
002:
003: {{IS_NOTE
004: Purpose:
005:
006: Description:
007:
008: History:
009: Wed Jan 16 14:37:13 2008, Created by gracelin
010: }}IS_NOTE
011:
012: Copyright (C) 2008 Potix Corporation. All Rights Reserved.
013:
014: {{IS_RIGHT
015: This program is distributed under GPL Version 2.0 in the hope that
016: it will be useful, but WITHOUT ANY WARRANTY.
017: }}IS_RIGHT
018: */
019: package org.zkoss.zkex.zul;
020:
021: import java.io.ByteArrayOutputStream;
022: import java.io.File;
023: import java.io.FileInputStream;
024: import java.io.IOException;
025: import java.io.InputStream;
026: import java.util.HashMap;
027: import java.util.Map;
028: import java.util.StringTokenizer;
029:
030: import net.sf.jasperreports.engine.JRDataSource;
031: import net.sf.jasperreports.engine.JREmptyDataSource;
032: import net.sf.jasperreports.engine.JRExporter;
033: import net.sf.jasperreports.engine.JRExporterParameter;
034: import net.sf.jasperreports.engine.JasperFillManager;
035: import net.sf.jasperreports.engine.JasperPrint;
036: import net.sf.jasperreports.engine.export.JExcelApiExporter;
037: import net.sf.jasperreports.engine.export.JRCsvExporter;
038: import net.sf.jasperreports.engine.export.JRHtmlExporter;
039: import net.sf.jasperreports.engine.export.JRHtmlExporterParameter;
040: import net.sf.jasperreports.engine.export.JRPdfExporter;
041: import net.sf.jasperreports.engine.export.JRRtfExporter;
042: import net.sf.jasperreports.engine.export.JRXlsExporter;
043: import net.sf.jasperreports.engine.export.JRXlsExporterParameter;
044: import net.sf.jasperreports.engine.export.JRXmlExporter;
045: import net.sf.jasperreports.engine.export.oasis.JROdtExporter;
046:
047: import org.zkoss.lang.Objects;
048: import org.zkoss.util.media.AMedia;
049: import org.zkoss.util.media.Media;
050: import org.zkoss.util.logging.Log;
051: import org.zkoss.xml.HTMLs;
052:
053: import org.zkoss.zk.ui.Executions;
054: import org.zkoss.zk.ui.Execution;
055: import org.zkoss.zk.ui.HtmlBasedComponent;
056: import org.zkoss.zk.ui.UiException;
057: import org.zkoss.zk.ui.ext.render.DynamicMedia;
058: import org.zkoss.zul.impl.Utils;
059:
060: /**
061: * The JasperReport component. It is used to generate a Jasper report into an
062: * inline frame.
063: *
064: * <p>
065: * Note: this component is serializable only if the data source ({@link #getDatasource})
066: * is serializable.
067: *
068: * @author gracelin
069: * @since 3.0.2
070: */
071: public class Jasperreport extends HtmlBasedComponent {
072: private static final Log log = Log.lookup(Jasperreport.class);
073: private static final long serialVersionUID = 20080117L;
074:
075: private static final String TASK_PDF = "pdf";
076: private static final String TASK_XML = "xml";
077: private static final String TASK_HTML = "html";
078: private static final String TASK_RTF = "rtf";
079: private static final String TASK_XLS = "xls";
080: private static final String TASK_JXL = "jxl";
081: private static final String TASK_CSV = "csv";
082: private static final String TASK_ODT = "odt";
083:
084: private String _src;
085: private Map _parameters;
086: private JRDataSource _datasource;
087: private int _medver;
088: private String _type = "pdf";
089: private JRExporter exporter;
090: private static final String IMAGE_DIR = "img/";
091:
092: public Jasperreport() {
093: setHeight("100%");
094: setWidth("100%");
095: }
096:
097: public Jasperreport(String src) {
098: setSrc(src);
099: }
100:
101: /**
102: * Returns the source (jasper file).
103: *
104: * @return src The compiled file (jasper file).
105: */
106: public String getSrc() {
107: return _src;
108: }
109:
110: /**
111: * Sets the source (jasper file).
112: * <p>
113: * If src is changed, the whole component is invalidate.
114: *
115: * @param src
116: * The compiled file (jasper file). If null or empty, nothing is
117: * included.
118: */
119: public void setSrc(String src) {
120: if (src != null && src.length() == 0)
121: src = null;
122: if (!Objects.equals(_src, src)) {
123: _src = src;
124: invalidate();
125: }
126: }
127:
128: /**
129: * Returns the attributes for generating the HTML tags.
130: */
131: public String getOuterAttrs() {
132: final String attrs = super .getOuterAttrs();
133: if (_src == null)
134: return attrs;
135:
136: final StringBuffer sb = new StringBuffer(80).append(attrs);
137: StringTokenizer st = new StringTokenizer(_src, ".");
138: HTMLs.appendAttribute(sb, "src", Utils.getDynamicMediaURI(this ,
139: _medver++, st.nextToken(), _type.equals("jxl") ? "xls"
140: : _type));
141:
142: return sb.toString();
143: }
144:
145: /**
146: * Returns the JasperReports Parameters.
147: */
148: public Map getParameters() {
149: return _parameters;
150: }
151:
152: /**
153: * Sets the JasperReports Parameters.
154: *
155: * @param parameters
156: * use to fill the report
157: */
158: public void setParameters(Map parameters) {
159: if (!Objects.equals(_parameters, parameters)) {
160: _parameters = parameters;
161: invalidate();
162: }
163: }
164:
165: /**
166: * Returns the JasperReports DataSource.
167: */
168: public JRDataSource getDatasource() {
169: return _datasource;
170: }
171:
172: /**
173: * Sets the JasperReports DataSource.
174: *
175: * @param dataSource
176: * use to fill the report
177: */
178: public void setDatasource(JRDataSource dataSource) {
179: if (!Objects.equals(_datasource, dataSource)) {
180: _datasource = dataSource;
181: invalidate();
182: }
183: }
184:
185: /**
186: * Returns the output file type.
187: * @since 3.0.3
188: */
189: public String getType() {
190: return _type;
191: }
192:
193: /**
194: * Sets the output file type.
195: * Allowed type: pdf, xml, html, rtf, xls, jxl, csv and odt.
196: * <dl>
197: * <dt>pdf</dt>
198: * <dd>The PDF format.</dd>
199: * <dt>rtf</dt>
200: * <dd>The RTF format (Rich Text Format).</dd>
201: * <dt>xls</dt>
202: * <dd>The Microsoft Excel format generated with <a href="http://poi.apache.org">Apache POI</a>.</dd>
203: * <dt>jxl</dt>
204: * <dd>The Microsoft Excel format generated with <a href="http://jexcelapi.sourceforge.net/">JExcelApi</a>.</dd>
205: * <dt>csv</dt>
206: * <dd>The CSV format (Comma-Separated Values)</dd>
207: * <dt>odt</dt>
208: * <dd>The OpenOffice Writer format</dd>
209: * </dl>
210: *
211: * @param type type of output file. If type is null, assign it a default value "pdf".
212: * @since 3.0.3
213: */
214: public void setType(String type) {
215: if (type == null)
216: type = "pdf";
217: if (!Objects.equals(_type, type)) {
218: _type = type;
219: invalidate();
220: }
221: }
222:
223: // -- ComponentCtrl --//
224: protected Object newExtraCtrl() {
225: return new ExtraCtrl();
226: }
227:
228: /**
229: * A utility class to implement {@link #getExtraCtrl}. It is used only by
230: * component developers.
231: */
232: protected class ExtraCtrl extends HtmlBasedComponent.ExtraCtrl
233: implements DynamicMedia {
234: // -- DynamicMedia --//
235: public Media getMedia(String pathInfo) {
236:
237: int indexOfImg = pathInfo.lastIndexOf(IMAGE_DIR);
238:
239: // path has IMAGE_DIR, it may be a image.
240: if (indexOfImg >= 0) {
241: String imageName = pathInfo.substring(indexOfImg
242: + IMAGE_DIR.length());
243:
244: // response file path has ".", it's not a image file
245: if (imageName.indexOf(".") < 0) {
246: return getImage(imageName);
247: }
248: }
249:
250: return doReport();
251: }
252: }
253:
254: /**
255: * Use the Parameters & Data sourse to produce report. If parameters are
256: * null, we will use an empty Map. If data source is null, use
257: * JREmptyDataSource.
258: *
259: * @return A AMedia contains report's byte stream.
260: */
261: private AMedia doReport() {
262:
263: InputStream is = null;
264:
265: try {
266: // get template file
267: if (is == null) {// try to load by web context.
268: final Execution exec = Executions.getCurrent();
269: is = exec.getDesktop().getWebApp().getResourceAsStream(
270: exec.toAbsoluteURI(_src, false));
271: if (is == null) {// try to load by class loader
272: is = Thread.currentThread().getContextClassLoader()
273: .getResourceAsStream(_src);
274: if (is == null) {// try to load by file
275: File fl = new File(_src);
276: if (!fl.exists())
277: throw new RuntimeException("resource for "
278: + _src + " not found.");
279:
280: is = new FileInputStream(fl);
281: }
282: }
283: }
284:
285: // Default value
286: if (_parameters == null)
287: _parameters = new HashMap();
288: if (_datasource == null)
289: _datasource = new JREmptyDataSource();
290:
291: // fill the report
292: JasperPrint jasperPrint = JasperFillManager.fillReport(is,
293: _parameters, _datasource);
294:
295: // export one type of report
296: if (TASK_PDF.equals(_type)) {
297:
298: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
299:
300: exporter = new JRPdfExporter();
301: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
302: jasperPrint);
303: exporter.setParameter(
304: JRExporterParameter.OUTPUT_STREAM,
305: arrayOutputStream);
306: exporter.exportReport();
307:
308: arrayOutputStream.close();
309: return new AMedia("report.pdf", "pdf",
310: "application/pdf", arrayOutputStream
311: .toByteArray());
312:
313: } else if (TASK_XML.equals(_type)) {
314:
315: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
316:
317: exporter = new JRXmlExporter();
318: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
319: jasperPrint);
320: exporter.setParameter(
321: JRExporterParameter.OUTPUT_STREAM,
322: arrayOutputStream);
323: exporter.exportReport();
324:
325: arrayOutputStream.close();
326: return new AMedia("report.xml", "xml", "text/xml",
327: arrayOutputStream.toByteArray());
328:
329: } else if (TASK_HTML.equals(_type)) {
330:
331: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
332:
333: exporter = new JRHtmlExporter();
334: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
335: jasperPrint);
336: exporter.setParameter(
337: JRExporterParameter.OUTPUT_STREAM,
338: arrayOutputStream);
339:
340: // set IMAGES_MAP parameter to prepare get backward IMAGE_MAP parameter
341: exporter.setParameter(
342: JRHtmlExporterParameter.IMAGES_MAP,
343: new HashMap());
344: exporter.setParameter(
345: JRHtmlExporterParameter.IMAGES_URI, IMAGE_DIR);
346: exporter.exportReport();
347:
348: arrayOutputStream.close();
349:
350: return new AMedia("report.html", "html", "text/html",
351: arrayOutputStream.toByteArray());
352:
353: } else if (TASK_RTF.equals(_type)) {
354:
355: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
356:
357: exporter = new JRRtfExporter();
358: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
359: jasperPrint);
360: exporter.setParameter(
361: JRExporterParameter.OUTPUT_STREAM,
362: arrayOutputStream);
363: exporter.exportReport();
364:
365: arrayOutputStream.close();
366: return new AMedia("report.rtf", "rtf",
367: "application/rtf", arrayOutputStream
368: .toByteArray());
369:
370: } else if (TASK_XLS.equals(_type)) {
371:
372: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
373:
374: exporter = new JRXlsExporter();
375: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
376: jasperPrint);
377: exporter.setParameter(
378: JRExporterParameter.OUTPUT_STREAM,
379: arrayOutputStream);
380: exporter.setParameter(
381: JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
382: Boolean.TRUE);
383: exporter.exportReport();
384:
385: arrayOutputStream.close();
386: return new AMedia("report.xls", "xls",
387: "application/vnd.ms-excel", arrayOutputStream
388: .toByteArray());
389:
390: } else if (TASK_JXL.equals(_type)) {
391:
392: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
393:
394: exporter = new JExcelApiExporter();
395: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
396: jasperPrint);
397: exporter.setParameter(
398: JRExporterParameter.OUTPUT_STREAM,
399: arrayOutputStream);
400: exporter.setParameter(
401: JRXlsExporterParameter.IS_ONE_PAGE_PER_SHEET,
402: Boolean.TRUE);
403: exporter.exportReport();
404:
405: arrayOutputStream.close();
406: return new AMedia("report.xls", "xls",
407: "application/vnd.ms-excel", arrayOutputStream
408: .toByteArray());
409:
410: } else if (TASK_CSV.equals(_type)) {
411:
412: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
413:
414: exporter = new JRCsvExporter();
415: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
416: jasperPrint);
417: exporter.setParameter(
418: JRExporterParameter.OUTPUT_STREAM,
419: arrayOutputStream);
420: exporter.exportReport();
421:
422: arrayOutputStream.close();
423: return new AMedia("report.csv", "csv", "text/csv",
424: arrayOutputStream.toByteArray());
425:
426: } else if (TASK_ODT.equals(_type)) {
427:
428: ByteArrayOutputStream arrayOutputStream = new ByteArrayOutputStream();
429:
430: exporter = new JROdtExporter();
431: exporter.setParameter(JRExporterParameter.JASPER_PRINT,
432: jasperPrint);
433: exporter.setParameter(
434: JRExporterParameter.OUTPUT_STREAM,
435: arrayOutputStream);
436: exporter.exportReport();
437:
438: arrayOutputStream.close();
439: return new AMedia("report.odt", "odt",
440: "application/vnd.oasis.opendocument.text",
441: arrayOutputStream.toByteArray());
442:
443: } else {
444: throw new UiException("Type: " + _type
445: + " is not supported in JasperReports.");
446: }
447:
448: } catch (Exception ex) {
449: throw UiException.Aide.wrap(ex);
450: } finally {
451: if (is != null) {
452: try {
453: is.close();
454: } catch (IOException e) {
455: log.warningBriefly("Ignored: unable to close", e);
456: }
457: }
458: }
459: }
460:
461: /**
462: * When output file type is HTML, return image in AMedia
463: *
464: * @param imageName the request image file name
465: * @return A AMdia contains a image.
466: */
467: private AMedia getImage(String imageName) {
468: Map imageMap = (Map) exporter
469: .getParameter(JRHtmlExporterParameter.IMAGES_MAP);
470:
471: byte[] imageBytes = (byte[]) imageMap.get(imageName);
472:
473: return new AMedia(imageName, "", "image/gif", imageBytes);
474: }
475: }
|