如下为制作好的模版,【A1:D1】处的注解用来标识模版的边界,使用${}来标识我们需要填充的数据。【A4】处理的注解来用遍历一个集合,我们对集合的每个元素取名为item,每个元素的又可以使用${item.属性}来进行获取
我们使用Maven来进行包依赖管理
<dependency> <groupId>org.jxls</groupId> <artifactId>jxls</artifactId> <version>2.2.7</version> </dependency> <dependency> <groupId>org.jxls</groupId> <artifactId>jxls-poi</artifactId> <version>1.0.6</version> </dependency> <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>3.13</version> </dependency> 123456789101112131415 123456789101112131415注意 使用Maven的 maven-resources-plugin 插件管理 resources 时,Maven会对模版进行转码处理,因此需要对xls格式的文件进行过滤,使其不处理。
<build> <plugins> <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-resources-plugin</artifactId> <version>2.6</version> <configuration> <nonFilteredFileExtensions> <nonFilteredFileExtension>pdf</nonFilteredFileExtension> <nonFilteredFileExtension>swf</nonFilteredFileExtension> <nonFilteredFileExtension>data</nonFilteredFileExtension> <nonFilteredFileExtension>xls</nonFilteredFileExtension> </nonFilteredFileExtensions> </configuration> </plugin> </plugins> </build> 1234567891011121314151617 1234567891011121314151617Spring提供了 AbstractExcelView 对提供对Excel导出的支持,继承该类的子类仅需要做Excel的处理。我们来看看Spring官网为我们提供的一个示例:
package excel; // imports omitted for brevity public class HomePage extends AbstractExcelView { protected void buildExcelDocument(Map model, HSSFWorkbook wb, HttpServletRequest req, HttpServletResponse resp) throws Exception { HSSFSheet sheet; HSSFRow sheetRow; HSSFCell cell; // Go to the first sheet // getSheetAt: only if wb is created from an existing document // sheet = wb.getSheetAt(0); sheet = wb.createSheet("Spring"); sheet.setDefaultColumnWidth((short) 12); // write a text at A1 cell = getCell(sheet, 0, 0); setText(cell, "Spring-Excel test"); List words = (List) model.get("wordList"); for (int i=0; i < words.size(); i++) { cell = getCell(sheet, 2+i, 0); setText(cell, (String) words.get(i)); } } } 12345678910111213141516171819202122232425262728293031 12345678910111213141516171819202122232425262728293031我们可以看到上面的例子中,我们需要对Excel进行一个个单元格的数据填充,这是一项很烦锁的工作。现在让我们来看下,Jxls与Spring MVC的结合如何优雅的完成Excel的导出。我们依旧使用上面所述的模版。
我们继承Spring提供的 AbstractView 抽象类。
import org.jxls.common.Context; import org.jxls.util.JxlsHelper; import org.springframework.web.servlet.view.AbstractView; import javax.servlet.ServletOutputStream; import javax.servlet.http.HttpServletRequest; import javax.servlet.http.HttpServletResponse; import java.io.InputStream; import java.io.UnsupportedEncodingException; import java.net.URLEncoder; import java.util.Map; public class JxlsExcelView extends AbstractView { private static final String CONTENT_TYPE = "application/vnd.ms-excel"; private String templatePath; private String exportFileName; /** * @param templatePath 模版相对于当前classpath路径 * @param exportFileName 导出文件名 */ public JxlsExcelView(String templatePath, String exportFileName) { this.templatePath = templatePath; if (exportFileName != null) { try { exportFileName = URLEncoder.encode(exportFileName, "UTF-8"); } catch (UnsupportedEncodingException e) { e.printStackTrace(); } } this.exportFileName = exportFileName; setContentType(CONTENT_TYPE); } @Override protected void renderMergedOutputModel( Map<String, Object> model, HttpServletRequest request, HttpServletResponse response) throws Exception { Context context = new Context(model); response.setContentType(getContentType()); response.setHeader("content-disposition", "attachment;filename=" + exportFileName + ".xls"); ServletOutputStream os = response.getOutputStream(); InputStream is = getClass().getClassLoader().getResourceAsStream(templatePath); JxlsHelper.getInstance().processTemplate(is, os, context); is.close(); } } 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950 1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950至此一个完整的Excel导出功能完成。是不是相当的简单及清晰?
以下为本人遇到过的问题,而本人实际使用的模版又较为复杂,有些问题需要跟踪代码来解决,因为错误提示有时不够友好。
数据没办法解析,编写模版时要格外仔细数据遍历时Shift Row的格式问题数据遍历时,集合为空问题Spring 官方文档 Jxls 官网文档
