在业务系统开发的时候经常能碰到excel文件导出的需求,在java中,excel文件导出有很多种实现方案,这里我介绍下jxls组件的实现方式。
为什么是jxls而不是其他的组件呢?
与阿里巴巴的EasyExcel这样直接数据对象的属性上使用注解标记的实现方式不同,jxls使用的是类jsp这样的模板形式,通过预先定义好excel模板实现数据的导出。个人感觉虽然jxls繁琐了一点,但是导出文件的样式和排版上jxls能有更好的灵活性(你把模板定义好就行了)
jxls的官网地址:http://jxls.sourceforge.net/index.html
首先引入maven依赖
<!-- jxls --> <dependency> <groupId>org.jxls</groupId> <artifactId>jxls</artifactId> <version>2.8.0</version> </dependency> <dependency> <groupId>org.jxls</groupId> <artifactId>jxls-poi</artifactId> <version>2.8.0</version> </dependency>
接下来就是导出模板的定义,我这里直接举一个导出用户列表的例子。新建一个excel文件:用户列表导出模板.xlsx 将它放在resources目录下
如上图是我们对excel的模板定义
${}是用来输出变量的。
图中单元格右上角带有红色小三角的该单元格加了批注,而一些如循环遍历数据等这些操作的语句就是写在批注中的。
excel模板的第一个单元格A1是固定要写批注的。批注内容为:jx:area(lastCell="D5") 意思是模板定义的覆盖范围为A1-D5,在这个覆盖范围内的标记会被jxls去解析填充对应的数据。

我在这里为了演示比较自由的定制化表格样式,我在右下角添加了一个导出时间和导出人。简单的是用${}标记进行输出。
至此我们的excel模板已经完工了,你会发现,其实跟jsp这种用模板开发html页面的形式完全一样,只是语法有点不同。
接下来我们实现数据填充的部分,直接展示controller层代码。service层代码仅用来获取模拟数据这里就不展示了。
@GetMapping("/export") public String export(HttpServletRequest request, HttpServletResponse response) { String exportTempName = "用户列表导出模板.xlsx"; String exportFileName = "用户列表导出.xlsx"; try { //获取数据 List<User> users = userService.listAll(); //设置jxls相关信息 Context context = new Context(); context.putVar("users", users); context.putVar("title","用户列表导出"); context.putVar("time", DateUtil.now()); context.putVar("exportUser", "王经理"); //加载模板 InputStream exIs = this.getClass().getResourceAsStream("/"+exportTempName); //生成导出文件 File tempFile = new File(System.getProperty("java.io.tmpdir") + File.separator + System.currentTimeMillis()); OutputStream os = new BufferedOutputStream(new FileOutputStream(tempFile)); JxlsHelper.getInstance().processTemplate(exIs, os, context); //导出下载 InputStream is = new BufferedInputStream(new FileInputStream(tempFile)); byte[] buffer = new byte[is.available()]; is.read(buffer); is.close(); response.reset(); response.addHeader("Content-Disposition", "attachment;filename=" + new String(exportFileName.getBytes(StandardCharsets.UTF_8), StandardCharsets.ISO_8859_1));
response.addHeader("Content-Length", "" +tempFile.length()); OutputStream toClient = new BufferedOutputStream(response.getOutputStream()); response.setContentType("application/octet-stream"); toClient.write(buffer); toClient.flush(); toClient.close(); return ""; } catch (Exception e) { e.printStackTrace(); return "文件下载出错"; } }
这里我们新建了一个Context用来存放生成表格的数据,类似于spring中的上下文。
之后加载模板的输入流还有生成的文件输出流
JxlsHelper.getInstance().processTemplate(exIs, os, context);
使用上述代码进行导出文件的生成,传入:模板的输入流,导出文件的输出流,数据context
到这我们需要导出的excel文件已经生成完毕了,controller中余下的部分其实是实现文件下载的功能,具体可以参考:SpringBoot如何实现文件下载功能
看一下最终导出的excel文件
完整代码参考:https://gitee.com/lqccan/blog-demo demo11