Jxls+Spring MVC实现Excel导出

xiaoxiao2021-02-28  105

Jxls+Spring MVC实现Excel导出 Excel导出功能是业务系统比较常见的功能,我们可以使用POI、Jexcel等来进行Excel的操作,然后再结合 spring MVC对两者的支持进行导出。但此方法的不足之处在于我们需要不厌其烦的进行Excel表格的操作。经过一番寻觅,发现了Jxls开源框架,使用模版生成导出文件。

初识Jxls

模版制作

如下为制作好的模版,【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 1234567891011121314151617

数据填充

try (InputStream is = Demo.class.getClassLoader().getResourceAsStream("template.xls")) { try (OutputStream os = new FileOutputStream("output.xls")) { Context context = new Context(); context.putVar("report_year", 2015); context.putVar("report_month", 8); //queryUser()为数据获取的方法 List<User> userList = queryUser(); context.putVar("users", userList); JxlsHelper.getInstance().processTemplate(is, os, context); } catch (IOException e) { e.printStackTrace(); } } catch (IOException e) { e.printStackTrace(); } 123456789101112131415 123456789101112131415

效果展示

与Spring MVC结合

Spring提供了 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的导出。我们依旧使用上面所述的模版。

编写View

我们继承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

请求处理

@RequestMapping(value = "/test") public ModelAndView export() { Map<String, Object> model = new HashMap<>(); model.put("report_year", 2015); model.put("report_month", 8); //queryUser()为数据获取的方法 List<User> userList = queryUser(); model.put("users", userList); return new ModelAndView(new JxlsExcelView("template.xls","output"), model); } 12345678910 12345678910

至此一个完整的Excel导出功能完成。是不是相当的简单及清晰?

相关及其它

其它支持

支持 jx:if 语法支持Excel 公式Jxls同时还提供了对Excel读取封装

以下为本人遇到过的问题,而本人实际使用的模版又较为复杂,有些问题需要跟踪代码来解决,因为错误提示有时不够友好。

数据没办法解析,编写模版时要格外仔细数据遍历时Shift Row的格式问题数据遍历时,集合为空问题

源码

引用

Spring 官方文档 Jxls 官网文档

转载请注明原文地址: https://www.6miu.com/read-38322.html

最新回复(0)