Browse Source
Introduces an AbstractXlsView and dedicated subclasses for POI's xmlx support. Deprecates the traditional AbstractExcelView which is based on pre POI 3.5 API. Issue: SPR-6898pull/759/head
7 changed files with 367 additions and 17 deletions
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
/* |
||||
* Copyright 2002-2015 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 org.springframework.web.servlet.view.document; |
||||
|
||||
import java.io.Closeable; |
||||
import java.io.IOException; |
||||
import java.util.Map; |
||||
import javax.servlet.ServletOutputStream; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
||||
import org.apache.poi.ss.usermodel.Workbook; |
||||
|
||||
import org.springframework.web.servlet.view.AbstractView; |
||||
|
||||
/** |
||||
* Convenient superclass for Excel document views in traditional XLS format. |
||||
* Compatible with Apache POI 3.5 and higher. |
||||
* |
||||
* <p>For working with the workbook in the subclass, see |
||||
* <a href="http://poi.apache.org">Apache's POI site</a> |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 4.2 |
||||
*/ |
||||
public abstract class AbstractXlsView extends AbstractView { |
||||
|
||||
/** |
||||
* Default Constructor. |
||||
* Sets the content type of the view to "application/vnd.ms-excel". |
||||
*/ |
||||
public AbstractXlsView() { |
||||
setContentType("application/vnd.ms-excel"); |
||||
} |
||||
|
||||
|
||||
@Override |
||||
protected boolean generatesDownloadContent() { |
||||
return true; |
||||
} |
||||
|
||||
/** |
||||
* Renders the Excel view, given the specified model. |
||||
*/ |
||||
@Override |
||||
protected final void renderMergedOutputModel( |
||||
Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
|
||||
// Create a fresh workbook instance for this render step.
|
||||
Workbook workbook = createWorkbook(model, request); |
||||
|
||||
// Delegate to application-provided document code.
|
||||
buildExcelDocument(model, workbook, request, response); |
||||
|
||||
// Set the content type.
|
||||
response.setContentType(getContentType()); |
||||
|
||||
// Flush byte array to servlet output stream.
|
||||
renderWorkbook(workbook, response);; |
||||
} |
||||
|
||||
|
||||
/** |
||||
* Template method for creating the POI {@link Workbook} instance. |
||||
* <p>The default implementation creates a traditional {@link HSSFWorkbook}. |
||||
* Spring-provided subclasses are overriding this for the OOXML-based variants; |
||||
* custom subclasses may override this for reading a workbook from a file. |
||||
* @param model the model Map |
||||
* @param request current HTTP request (for taking the URL or headers into account) |
||||
* @return the new {@link Workbook} instance |
||||
*/ |
||||
protected Workbook createWorkbook(Map<String, Object> model, HttpServletRequest request) { |
||||
return new HSSFWorkbook(); |
||||
} |
||||
|
||||
/** |
||||
* The actual render step: taking the POI {@link Workbook} and rendering |
||||
* it to the given response. |
||||
* @param workbook the POI Workbook to render |
||||
* @param response current HTTP response |
||||
* @throws IOException when thrown by I/O methods that we're delegating to |
||||
*/ |
||||
protected void renderWorkbook(Workbook workbook, HttpServletResponse response) throws IOException { |
||||
ServletOutputStream out = response.getOutputStream(); |
||||
workbook.write(out); |
||||
out.flush(); |
||||
|
||||
// Closeable only implemented as of POI 3.10
|
||||
if (workbook instanceof Closeable) { |
||||
((Closeable) workbook).close(); |
||||
} |
||||
} |
||||
|
||||
/** |
||||
* Application-provided subclasses must implement this method to populate |
||||
* the Excel workbook document, given the model. |
||||
* @param model the model Map |
||||
* @param workbook the Excel workbook to populate |
||||
* @param request in case we need locale etc. Shouldn't look at attributes. |
||||
* @param response in case we need to set cookies. Shouldn't write to it. |
||||
*/ |
||||
protected abstract void buildExcelDocument( |
||||
Map<String, Object> model, Workbook workbook, HttpServletRequest request, HttpServletResponse response) |
||||
throws Exception; |
||||
|
||||
} |
||||
@ -0,0 +1,59 @@
@@ -0,0 +1,59 @@
|
||||
/* |
||||
* Copyright 2002-2015 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 org.springframework.web.servlet.view.document; |
||||
|
||||
import java.io.IOException; |
||||
import java.util.Map; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.apache.poi.ss.usermodel.Workbook; |
||||
import org.apache.poi.xssf.streaming.SXSSFWorkbook; |
||||
|
||||
/** |
||||
* Convenient superclass for Excel document views in the Office 2007 XLSX format, |
||||
* using POI's streaming variant. Compatible with Apache POI 3.9 and higher. |
||||
* |
||||
* <p>For working with the workbook in the subclass, see |
||||
* <a href="http://poi.apache.org">Apache's POI site</a> |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 4.2 |
||||
*/ |
||||
public abstract class AbstractXlsxStreamingView extends AbstractXlsxView { |
||||
|
||||
/** |
||||
* This implementation creates a {@link SXSSFWorkbook} for streaming the XLSX format. |
||||
*/ |
||||
@Override |
||||
protected SXSSFWorkbook createWorkbook(Map<String, Object> model, HttpServletRequest request) { |
||||
return new SXSSFWorkbook(); |
||||
} |
||||
|
||||
/** |
||||
* This implementation disposes the {@link SXSSFWorkbook} when done with rendering. |
||||
* @see org.apache.poi.xssf.streaming.SXSSFWorkbook#dispose() |
||||
*/ |
||||
@Override |
||||
protected void renderWorkbook(Workbook workbook, HttpServletResponse response) throws IOException { |
||||
super.renderWorkbook(workbook, response); |
||||
|
||||
// Dispose temporary files in case of streaming variant...
|
||||
((SXSSFWorkbook) workbook).dispose(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,54 @@
@@ -0,0 +1,54 @@
|
||||
/* |
||||
* Copyright 2002-2015 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 org.springframework.web.servlet.view.document; |
||||
|
||||
import java.util.Map; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
|
||||
import org.apache.poi.ss.usermodel.Workbook; |
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
||||
|
||||
/** |
||||
* Convenient superclass for Excel document views in the Office 2007 XLSX format |
||||
* (as supported by POI-OOXML). Compatible with Apache POI 3.5 and higher. |
||||
* |
||||
* <p>For working with the workbook in the subclass, see |
||||
* <a href="http://poi.apache.org">Apache's POI site</a> |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 4.2 |
||||
*/ |
||||
public abstract class AbstractXlsxView extends AbstractXlsView { |
||||
|
||||
/** |
||||
* Default Constructor. |
||||
* Sets the content type of the view to |
||||
* "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet". |
||||
*/ |
||||
public AbstractXlsxView() { |
||||
setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); |
||||
} |
||||
|
||||
/** |
||||
* This implementation creates an {@link XSSFWorkbook} for the XLSX format. |
||||
*/ |
||||
@Override |
||||
protected Workbook createWorkbook(Map<String, Object> model, HttpServletRequest request) { |
||||
return new XSSFWorkbook(); |
||||
} |
||||
|
||||
} |
||||
@ -0,0 +1,121 @@
@@ -0,0 +1,121 @@
|
||||
/* |
||||
* Copyright 2002-2015 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 org.springframework.web.servlet.view.document; |
||||
|
||||
import java.io.ByteArrayInputStream; |
||||
import java.util.HashMap; |
||||
import java.util.Map; |
||||
import javax.servlet.http.HttpServletRequest; |
||||
import javax.servlet.http.HttpServletResponse; |
||||
|
||||
import org.apache.poi.hssf.usermodel.HSSFWorkbook; |
||||
import org.apache.poi.ss.usermodel.Cell; |
||||
import org.apache.poi.ss.usermodel.Row; |
||||
import org.apache.poi.ss.usermodel.Sheet; |
||||
import org.apache.poi.ss.usermodel.Workbook; |
||||
import org.apache.poi.xssf.usermodel.XSSFWorkbook; |
||||
import org.junit.Test; |
||||
|
||||
import org.springframework.mock.web.test.MockHttpServletRequest; |
||||
import org.springframework.mock.web.test.MockHttpServletResponse; |
||||
import org.springframework.web.servlet.View; |
||||
|
||||
import static org.junit.Assert.*; |
||||
|
||||
/** |
||||
* Tests for AbstractXlsView and its subclasses. |
||||
* |
||||
* @author Juergen Hoeller |
||||
* @since 4.2 |
||||
*/ |
||||
public class XlsViewTests { |
||||
|
||||
private final MockHttpServletRequest request = new MockHttpServletRequest(); |
||||
|
||||
private final MockHttpServletResponse response = new MockHttpServletResponse(); |
||||
|
||||
|
||||
@Test |
||||
public void testXls() throws Exception { |
||||
View excelView = new AbstractXlsView() { |
||||
@Override |
||||
protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, |
||||
HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
Sheet sheet = workbook.createSheet("Test Sheet"); |
||||
Row row = sheet.createRow(0); |
||||
Cell cell = row.createCell(0); |
||||
cell.setCellValue("Test Value"); |
||||
} |
||||
}; |
||||
|
||||
excelView.render(new HashMap<String, Object>(), request, response); |
||||
|
||||
Workbook wb = new HSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray())); |
||||
assertEquals("Test Sheet", wb.getSheetName(0)); |
||||
Sheet sheet = wb.getSheet("Test Sheet"); |
||||
Row row = sheet.getRow(0); |
||||
Cell cell = row.getCell(0); |
||||
assertEquals("Test Value", cell.getStringCellValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void testXlsxView() throws Exception { |
||||
View excelView = new AbstractXlsxView() { |
||||
@Override |
||||
protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, |
||||
HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
Sheet sheet = workbook.createSheet("Test Sheet"); |
||||
Row row = sheet.createRow(0); |
||||
Cell cell = row.createCell(0); |
||||
cell.setCellValue("Test Value"); |
||||
} |
||||
}; |
||||
|
||||
excelView.render(new HashMap<String, Object>(), request, response); |
||||
|
||||
Workbook wb = new XSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray())); |
||||
assertEquals("Test Sheet", wb.getSheetName(0)); |
||||
Sheet sheet = wb.getSheet("Test Sheet"); |
||||
Row row = sheet.getRow(0); |
||||
Cell cell = row.getCell(0); |
||||
assertEquals("Test Value", cell.getStringCellValue()); |
||||
} |
||||
|
||||
@Test |
||||
public void testXlsxStreamingView() throws Exception { |
||||
View excelView = new AbstractXlsxStreamingView() { |
||||
@Override |
||||
protected void buildExcelDocument(Map<String, Object> model, Workbook workbook, |
||||
HttpServletRequest request, HttpServletResponse response) throws Exception { |
||||
Sheet sheet = workbook.createSheet("Test Sheet"); |
||||
Row row = sheet.createRow(0); |
||||
Cell cell = row.createCell(0); |
||||
cell.setCellValue("Test Value"); |
||||
} |
||||
}; |
||||
|
||||
excelView.render(new HashMap<String, Object>(), request, response); |
||||
|
||||
Workbook wb = new XSSFWorkbook(new ByteArrayInputStream(response.getContentAsByteArray())); |
||||
assertEquals("Test Sheet", wb.getSheetName(0)); |
||||
Sheet sheet = wb.getSheet("Test Sheet"); |
||||
Row row = sheet.getRow(0); |
||||
Cell cell = row.getCell(0); |
||||
assertEquals("Test Value", cell.getStringCellValue()); |
||||
} |
||||
|
||||
} |
||||
Loading…
Reference in new issue