001/* 002 * Copyright 2002-2013 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * https://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.web.servlet.view.document; 018 019import java.io.OutputStream; 020import java.util.Locale; 021import java.util.Map; 022import javax.servlet.http.HttpServletRequest; 023import javax.servlet.http.HttpServletResponse; 024 025import jxl.Workbook; 026import jxl.write.WritableWorkbook; 027 028import org.springframework.core.io.Resource; 029import org.springframework.core.io.support.LocalizedResourceHelper; 030import org.springframework.web.servlet.support.RequestContextUtils; 031import org.springframework.web.servlet.view.AbstractView; 032 033/** 034 * Convenient superclass for Excel document views. 035 * 036 * <p>This class uses the <i>JExcelAPI</i> instead of <i>POI</i>. 037 * More information on <i>JExcelAPI</i> can be found on their 038 * <a href="http://www.andykhan.com/jexcelapi/" target="_blank">website</a>. 039 * 040 * <p>Properties: 041 * <ul> 042 * <li>url (optional): The url of an existing Excel document to pick as a 043 * starting point. It is done without localization part nor the .xls extension. 044 * </ul> 045 * 046 * <p>The file will be searched with locations in the following order: 047 * <ul> 048 * <li>[url]_[language]_[country].xls 049 * <li>[url]_[language].xls 050 * <li>[url].xls 051 * </ul> 052 * 053 * <p>For working with the workbook in the subclass, see <a 054 * href="http://www.andykhan.com/jexcelapi/">Java Excel API site</a> 055 * 056 * <p>As an example, you can try this snippet: 057 * 058 * <pre class="code"> 059 * protected void buildExcelDocument( 060 * Map<String, Object> model, WritableWorkbook workbook, 061 * HttpServletRequest request, HttpServletResponse response) { 062 * 063 * if (workbook.getNumberOfSheets() == 0) { 064 * workbook.createSheet("Spring", 0); 065 * } 066 * 067 * WritableSheet sheet = workbook.getSheet("Spring"); 068 * Label label = new Label(0, 0, "This is a nice label"); 069 * sheet.addCell(label); 070 * }</pre> 071 * 072 * The use of this view is close to the {@link AbstractExcelView} class, 073 * just using the JExcel API instead of the Apache POI API. 074 * 075 * @author Bram Smeets 076 * @author Alef Arendsen 077 * @author Juergen Hoeller 078 * @since 1.2.5 079 * @see AbstractExcelView 080 * @see AbstractPdfView 081 * @deprecated as of Spring 4.0, since JExcelAPI is an abandoned project 082 * (no release since 2009, with serious bugs remaining) 083 */ 084@Deprecated 085public abstract class AbstractJExcelView extends AbstractView { 086 087 /** The content type for an Excel response */ 088 private static final String CONTENT_TYPE = "application/vnd.ms-excel"; 089 090 /** The extension to look for existing templates */ 091 private static final String EXTENSION = ".xls"; 092 093 094 /** The url at which the template to use is located */ 095 private String url; 096 097 098 /** 099 * Default Constructor. 100 * Sets the content type of the view to "application/vnd.ms-excel". 101 */ 102 public AbstractJExcelView() { 103 setContentType(CONTENT_TYPE); 104 } 105 106 /** 107 * Set the URL of the Excel workbook source, without localization part nor extension. 108 */ 109 public void setUrl(String url) { 110 this.url = url; 111 } 112 113 114 @Override 115 protected boolean generatesDownloadContent() { 116 return true; 117 } 118 119 /** 120 * Renders the Excel view, given the specified model. 121 */ 122 @Override 123 protected final void renderMergedOutputModel( 124 Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { 125 126 // Set the content type and get the output stream. 127 response.setContentType(getContentType()); 128 OutputStream out = response.getOutputStream(); 129 130 WritableWorkbook workbook; 131 if (this.url != null) { 132 Workbook template = getTemplateSource(this.url, request); 133 workbook = Workbook.createWorkbook(out, template); 134 } 135 else { 136 logger.debug("Creating Excel Workbook from scratch"); 137 workbook = Workbook.createWorkbook(out); 138 } 139 140 buildExcelDocument(model, workbook, request, response); 141 142 // Should we set the content length here? 143 // response.setContentLength(workbook.getBytes().length); 144 145 workbook.write(); 146 out.flush(); 147 workbook.close(); 148 } 149 150 /** 151 * Create the workbook from an existing XLS document. 152 * @param url the URL of the Excel template without localization part nor extension 153 * @param request current HTTP request 154 * @return the template workbook 155 * @throws Exception in case of failure 156 */ 157 protected Workbook getTemplateSource(String url, HttpServletRequest request) throws Exception { 158 LocalizedResourceHelper helper = new LocalizedResourceHelper(getApplicationContext()); 159 Locale userLocale = RequestContextUtils.getLocale(request); 160 Resource inputFile = helper.findLocalizedResource(url, EXTENSION, userLocale); 161 162 // Create the Excel document from the source. 163 if (logger.isDebugEnabled()) { 164 logger.debug("Loading Excel workbook from " + inputFile); 165 } 166 return Workbook.getWorkbook(inputFile.getInputStream()); 167 } 168 169 /** 170 * Subclasses must implement this method to create an Excel Workbook 171 * document, given the model. 172 * @param model the model Map 173 * @param workbook the Excel workbook to complete 174 * @param request in case we need locale etc. Shouldn't look at attributes. 175 * @param response in case we need to set cookies. Shouldn't write to it. 176 * @throws Exception in case of failure 177 */ 178 protected abstract void buildExcelDocument(Map<String, Object> model, WritableWorkbook workbook, 179 HttpServletRequest request, HttpServletResponse response) throws Exception; 180 181}