Java tutorial
/* * Copyright 2002-2010 the original author or authors. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package ua.com.manometer.jasperreports; import java.io.UnsupportedEncodingException; import java.net.MalformedURLException; import java.net.URISyntaxException; import java.net.URL; import java.net.URLEncoder; import java.util.HashMap; import java.util.Map; import java.util.Properties; import java.util.Set; import javax.servlet.http.HttpServletResponse; import com.sun.jndi.toolkit.url.Uri; import net.sf.jasperreports.engine.JasperPrint; import org.apache.commons.lang.StringUtils; import org.springframework.beans.BeanUtils; import org.springframework.util.CollectionUtils; /** * Jasper Reports view class that allows for the actual rendering format to be * specified at runtime using a parameter contained in the model. * <p/> * <p>This view works on the concept of a format key and a mapping key. * The format key is used to pass the mapping key from your * <code>Controller</code> to Spring through as part of the model and the * mapping key is used to map a logical format to an actual JasperReports * view class. For example you might add the following code to your * <code>Controller</code>: * <p/> * <pre> * Map<String, Object> model = new HashMap<String, Object>(); * model.put("format", "pdf");</pre> * * Here <code>format</code> is the format key and <code>pdf</code> is * the mapping key. When rendering a report, this class looks for a * model parameter under the format key, which by default is * <code>format</code>. It then uses the value of this parameter to lookup * the actual <code>View</code> class to use. The default mappings for this * lookup are: * * <p><ul> * <li><code>csv</code> - <code>JasperReportsCsvView</code></li> * <li><code>html</code> - <code>JasperReportsHtmlView</code></li> * <li><code>pdf</code> - <code>JasperReportsPdfView</code></li> * <li><code>xls</code> - <code>JasperReportsXlsView</code></li> * </ul> * * <p>The format key can be changed using the <code>formatKey</code> * property and the mapping key to view class mappings can be changed using the * <code>formatMappings</code> property. * * @author Rob Harrop * @author Juergen Hoeller * @see #setFormatKey * @see #setFormatMappings * @since 1.1.5 */ public class JasperReportsMultiFormatView extends AbstractJasperReportsView { /** * Default value used for format key: "format" */ public static final String DEFAULT_FORMAT_KEY = "format"; /** * The key of the model parameter that holds the format key. */ private String formatKey = DEFAULT_FORMAT_KEY; /** * Stores the format mappings, with the format discriminator * as key and the corresponding view class as value. */ private Map<String, Class<? extends AbstractJasperReportsView>> formatMappings; /** * Creates a new <code>JasperReportsMultiFormatView</code> instance * with a default set of mappings. */ public JasperReportsMultiFormatView() { this.formatMappings = new HashMap<String, Class<? extends AbstractJasperReportsView>>(4); this.formatMappings.put("csv", JasperReportsCsvView.class); this.formatMappings.put("html", JasperReportsHtmlView.class); this.formatMappings.put("pdf", JasperReportsPdfView.class); this.formatMappings.put("xls", JasperReportsXlsView.class); this.formatMappings.put("odt", JasperReportsOdtView.class); } /** * Set the key of the model parameter that holds the format discriminator. * Default is "format". */ public void setFormatKey(String formatKey) { this.formatKey = formatKey; } /** * Set the mappings of format discriminators to view class names. * The default mappings are: * <p><ul> * <li><code>csv</code> - <code>JasperReportsCsvView</code></li> * <li><code>html</code> - <code>JasperReportsHtmlView</code></li> * <li><code>pdf</code> - <code>JasperReportsPdfView</code></li> * <li><code>xls</code> - <code>JasperReportsXlsView</code></li> * </ul> */ public void setFormatMappings(Map<String, Class<? extends AbstractJasperReportsView>> formatMappings) { if (CollectionUtils.isEmpty(formatMappings)) { throw new IllegalArgumentException("'formatMappings' must not be empty"); } this.formatMappings = formatMappings; } @Override protected boolean generatesDownloadContent() { return true; } /** * Locates the format key in the model using the configured discriminator key and uses this * key to lookup the appropriate view class from the mappings. The rendering of the * report is then delegated to an instance of that view class. */ @Override protected void renderReport(JasperPrint populatedReport, Map<String, Object> model, HttpServletResponse response) throws Exception { String format = (String) model.get(this.formatKey); if (format == null) { throw new IllegalArgumentException("No format format found in model"); } if (logger.isDebugEnabled()) { logger.debug("Rendering report using format mapping key [" + format + "]"); } Class<? extends AbstractJasperReportsView> viewClass = this.formatMappings.get(format); if (viewClass == null) { throw new IllegalArgumentException("Format discriminator [" + format + "] is not a configured mapping"); } if (logger.isDebugEnabled()) { logger.debug("Rendering report using view class [" + viewClass.getName() + "]"); } AbstractJasperReportsView view = BeanUtils.instantiateClass(viewClass); // Can skip most initialization since all relevant URL processing // has been done - just need to convert parameters on the sub view. view.setExporterParameters(getExporterParameters()); view.setConvertedExporterParameters(getConvertedExporterParameters()); String fileName = (String) model.get("name"); populateContentDispositionIfNecessary(response, format, fileName); view.renderReport(populatedReport, model, response); } private void populateContentDispositionIfNecessary(HttpServletResponse response, String format, String name) { if (StringUtils.isEmpty(name)) { name = "file"; } String encode = null; try { encode = URLEncoder.encode(name + "." + format, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); //To change body of catch statement use File | Settings | File Templates. } // String encode ="%D0%9C%D0%BE%D0%B9%20%D1%84%D0%B0%D0%B9%D0%BB.doc"; // String header = "attachment;filename=\"" + encode + "\""; response.setHeader(HEADER_CONTENT_DISPOSITION, header); } }