SpringBoot使用jxls组件实现可定制excel文件导出功能

在业务系统开发的时候经常能碰到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去解析填充对应的数据。


在A3单元格的位置也有一个批注,因为第3行这一行是需要进行遍历list进而填充数据的。遍历数据的批注为:jx:each(items="users" var="user" lastCell="D3") 意思是遍历users这个list,跟java中的for语句基本类似。lastCell的值就是该行的覆盖范围是覆盖到D3单元格


我在这里为了演示比较自由的定制化表格样式,我在右下角添加了一个导出时间和导出人。简单的是用${}标记进行输出。

至此我们的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("UTF-8"), "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/floow/blog-demo demo11

支付宝搜索:344355 领取随机红包

如果文章对您有帮助,欢迎给作者打赏