001/* 002 * Copyright 2002-2017 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.IOException; 020import java.util.Map; 021 022import javax.servlet.ServletOutputStream; 023import javax.servlet.http.HttpServletRequest; 024import javax.servlet.http.HttpServletResponse; 025 026import org.apache.poi.hssf.usermodel.HSSFWorkbook; 027import org.apache.poi.ss.usermodel.Workbook; 028 029import org.springframework.web.servlet.view.AbstractView; 030 031/** 032 * Convenient superclass for Excel document views in traditional XLS format. 033 * Compatible with Apache POI 3.5 and higher. 034 * 035 * <p>For working with the workbook in the subclass, see 036 * <a href="https://poi.apache.org">Apache's POI site</a> 037 * 038 * @author Juergen Hoeller 039 * @since 4.2 040 */ 041public abstract class AbstractXlsView extends AbstractView { 042 043 /** 044 * Default Constructor. 045 * Sets the content type of the view to "application/vnd.ms-excel". 046 */ 047 public AbstractXlsView() { 048 setContentType("application/vnd.ms-excel"); 049 } 050 051 052 @Override 053 protected boolean generatesDownloadContent() { 054 return true; 055 } 056 057 /** 058 * Renders the Excel view, given the specified model. 059 */ 060 @Override 061 protected final void renderMergedOutputModel( 062 Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { 063 064 // Create a fresh workbook instance for this render step. 065 Workbook workbook = createWorkbook(model, request); 066 067 // Delegate to application-provided document code. 068 buildExcelDocument(model, workbook, request, response); 069 070 // Set the content type. 071 response.setContentType(getContentType()); 072 073 // Flush byte array to servlet output stream. 074 renderWorkbook(workbook, response); 075 } 076 077 078 /** 079 * Template method for creating the POI {@link Workbook} instance. 080 * <p>The default implementation creates a traditional {@link HSSFWorkbook}. 081 * Spring-provided subclasses are overriding this for the OOXML-based variants; 082 * custom subclasses may override this for reading a workbook from a file. 083 * @param model the model Map 084 * @param request current HTTP request (for taking the URL or headers into account) 085 * @return the new {@link Workbook} instance 086 */ 087 protected Workbook createWorkbook(Map<String, Object> model, HttpServletRequest request) { 088 return new HSSFWorkbook(); 089 } 090 091 /** 092 * The actual render step: taking the POI {@link Workbook} and rendering 093 * it to the given response. 094 * @param workbook the POI Workbook to render 095 * @param response current HTTP response 096 * @throws IOException when thrown by I/O methods that we're delegating to 097 */ 098 protected void renderWorkbook(Workbook workbook, HttpServletResponse response) throws IOException { 099 ServletOutputStream out = response.getOutputStream(); 100 workbook.write(out); 101 workbook.close(); 102 } 103 104 /** 105 * Application-provided subclasses must implement this method to populate 106 * the Excel workbook document, given the model. 107 * @param model the model Map 108 * @param workbook the Excel workbook to populate 109 * @param request in case we need locale etc. Shouldn't look at attributes. 110 * @param response in case we need to set cookies. Shouldn't write to it. 111 */ 112 protected abstract void buildExcelDocument( 113 Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) 114 throws Exception; 115 116}