springboot使用EasyExcel导出数据

springboot使用EasyExcel导出数据

简介:本文主要描述使用EasyExcel导出数据的简单流程,事实上企业需求一般都比较简单,就是表单数据输出到Excel即可,如果数据量大的话,为了避免占用内存过高或者OOM,使用多次读数据多次写入的方法,下面就简单介绍下两种情景的实现。

1. 导入依赖

<!-- Easy Excel -->
<dependency>
    <groupId>com.alibaba</groupId>
    <artifactId>easyexcel</artifactId>
    <version>3.2.1</version>
</dependency>

2. 建立对应实体类

例如我要导出的Excel数据格式为

image-20231214213222344.png
首先创建实体类:

@Getter
@Setter
@ToString
public class UserInfoForExcel {
    @ExcelProperty("ID")		// 标注字段对应Excel列行头
    private String userId;
    @ExcelProperty("账号")
    private String account;
    @ExcelProperty("邮箱")
    private String email;
    @ExcelProperty("昵称")
    private String nickname;
    @ExcelProperty("年龄")
    private Integer age;
    @ExcelProperty("生日")
    @DateTimeFormat("yyyy-MM-dd")
    private Date birthday;
}

3. 创建处理方法

假如流程为 前端发送get请求,后端controller接收提交给service处理,service从dao中获取数据后生成excel表,然后将excel的路径返回给前端(一般需求肯定是URL或者URI,此处只做演示,不做URL处理,直接返回路径)

service处理方法代码如下

    /**
     * 从数据库读取所有数据,使用EasyExcel生成表格
     * @return
     */
    public String handleExcelOutput() {
        String fileName = "D://data/" + "user_info_" + System.currentTimeMillis() + ".xlsx";
        UserInfoData userInfoData = new UserInfoData();     // 从数据库获取数据的dao
        EasyExcel.write(fileName, UserInfoForExcel.class)
                .sheet("模板")
                .doWrite(userInfoData.getUserInfoList());   // 写Excel
        return fileName;
    }

下面是模拟数据库获取数据操作,可以忽略

@Getter
@Setter
@ToString
public class UserInfoData {
    /**
     * 模拟数据库获取数据
     */
    public List<UserInfoForExcel> getUserInfoList() {
        List<UserInfoForExcel> list = new ArrayList<>();
        for (int i = 1; i < 18; i++){
            UserInfoForExcel userInfoForExcel = new UserInfoForExcel();
            userInfoForExcel.setUserId("00"+i);
            userInfoForExcel.setAge(16+i);
            userInfoForExcel.setAccount("account"+i);
            userInfoForExcel.setNickname("nick "+ i);
            userInfoForExcel.setEmail("123"+i+"@123.com");
            try {
                userInfoForExcel.setBirthday(new SimpleDateFormat("yyyy-MM-dd").parse("1997-06-1"+i));
            } catch (ParseException e) {
                // 测试demo,不做处理
                throw new RuntimeException(e);
            }
            list.add(userInfoForExcel);
        }
        System.out.println(list);
        return list;
    }
}

4. 测试接口

@RestController
@RequestMapping("userinfo")
public class UserInfoController {

    @Autowired
    UserService userService;

    @GetMapping("output")
    public String handleExcelOutput() throws ParseException {
        String s = userService.handleExcelOutput();
        return s;
    }
}

5. 测试结果

在设定的文件路径中可以看到生成的Excel表

image-20231214214943113.png

6. 分批写到Excel

上面的例子是将数据一次性读取后写到excel,占用内存过大,可以分多次写入,service方法如下

    /**
     * 从数据库分页读取数据,使用EasyExcel,分多次写入Excel
     * @return
     */
    public String handleExcelOutputOnPage() {
        String fileName = "D://data/" + "user_info_" + System.currentTimeMillis() + ".xlsx";
        UserInfoData userInfoData = new UserInfoData();     // 从数据库获取数据的dao
        // 这里 需要指定写用哪个class去写
        try (ExcelWriter excelWriter = EasyExcel.write(fileName, UserInfoForExcel.class).build()) {
            WriteSheet writeSheet = EasyExcel.writerSheet("模板").build();
            // 去调用写入,这里我调用了五次,实际使用时根据数据库分页的总的页数来
            // 例如数据库中数据位1000条,每次写入100条,则i为Math.ceil(1000/100),向上取整
            for (int i = 0; i < 5; i++) {
                // 分页去数据库查询数据 这里可以去数据库查询每一页的数据
                // 通过设置limit值获取不同页数据
                List<UserInfoForExcel> userInfoList = userInfoData.getUserInfoList();
                excelWriter.write(userInfoList, writeSheet);
            }
        }
        return fileName;
    }

7. 最后

以上就是全文内容,最后还是提醒,这只是最简单的需求和实现方法,事实上EasyExcel还能实现其他有趣的功能,建议去官网看文档

官网地址:https://easyexcel.opensource.alibaba.com/

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
使用EasyExcel导出Excel时,你可以通过添加一个序号列来实现自增的编号。下面是一个示例,演示如何在导出Excel时添加自增的序号列: ```java import com.alibaba.excel.EasyExcel; import com.alibaba.excel.write.builder.ExcelWriterBuilder; import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder; import org.springframework.stereotype.Controller; import org.springframework.web.bind.annotation.GetMapping; import javax.servlet.http.HttpServletResponse; import java.io.IOException; import java.util.ArrayList; import java.util.List; @Controller public class ExcelController { @GetMapping("/export") public void exportExcel(HttpServletResponse response) throws IOException { // 创建数据列表 List<User> userList = new ArrayList<>(); userList.add(new User("张三", 20)); userList.add(new User("李四", 25)); userList.add(new User("王五", 30)); // 添加序号列 List<UserWithIndex> userListWithIndex = new ArrayList<>(); for (int i = 0; i < userList.size(); i++) { User user = userList.get(i); UserWithIndex userWithIndex = new UserWithIndex(i + 1, user.getName(), user.getAge()); userListWithIndex.add(userWithIndex); } // 设置响应头 response.setHeader("Content-Disposition", "attachment; filename=example.xlsx"); response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"); // 创建Excel写入器 ExcelWriterBuilder writerBuilder = EasyExcel.write(response.getOutputStream(), UserWithIndex.class); // 创建工作表 ExcelWriterSheetBuilder sheetBuilder = writerBuilder.sheet("Sheet1"); // 写入数据 sheetBuilder.doWrite(userListWithIndex); // 关闭写入器 writerBuilder.finish(); } // 定义用户实体类 public static class User { private String name; private int age; // 省略构造函数、getter和setter } // 带序号的用户实体类 public static class UserWithIndex { private int index; private String name; private int age; public UserWithIndex(int index, String name, int age) { this.index = index; this.name = name; this.age = age; } // 省略getter和setter } } ``` 在上述代码中,我们创建了一个新的 `UserWithIndex` 类,它包含了一个 `index` 属性来表示序号。在导出Excel之前,我们将原始数据列表转换为带序号的数据列表,并将其用于写入Excel。 确保在项目的依赖中包含了EasyExcel库的相关依赖项。运行该代码后,你将会得到一个带有自增序号列的Excel文件。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值