使用easypoi实现动态列导出表格

前言

我们经常使用easypoi的@Excel注解来标注列名,但是想实现动态列该怎么办

主要是阅读以下博客的内容并实践

使用 easypoi 导出 excel 实现动态列,完美解决!-腾讯云开发者社区-腾讯云 (tencent.com)

如有错误请指正

依赖

<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-spring-boot-starter</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-base</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-web</artifactId>
    <version>4.2.0</version>
</dependency>
<dependency>
    <groupId>cn.afterturn</groupId>
    <artifactId>easypoi-annotation</artifactId>
    <version>4.2.0</version>
</dependency>

思路

就是自己单独拎出来一个方法,用来构建列名。然后将展示的数据转化成HashMap格式。key为构建该列时设置的key,value为你想在表格中展示的数据,接下来我用一个demo来演示下

需求

学校会定时发给学生新玩具,现在要统计学生拥有玩具的数量

代码及解析

传输类
public class ExcelDTO {
    /**
     * 学生姓名
     */
    private String studentName;
    /**
     * 学生学号
     */
    private Integer uid;
    /**
     * 学生拥有的玩具数量列表
     */
    private List<ToyDTO> toyDTOList;
}
public class ToyDTO {

    /**
     * 玩具名
     */
    private String toyName;

    /**
     * 玩具编码
     */
    private String toyCode;

    /**
     * 学生拥有的玩具数量
     */
    private Integer quantity;
}

以上两个类的关系很简单,就是一个学生会拥有多个玩具,也就有多个玩具拥有的数量关系

控制逻辑层(为了方便,我把业务逻辑写在controller里面)
@RestController
@RequestMapping("/dynamic")
public class DynamicExcelController {
    @GetMapping(value = "/excel/export")
    public void exportDynamicExcel(HttpServletResponse response){
        //构建数据(模拟从数据库中查询出来的数据)
        //用玩具的名称当作列名,而玩具的种类是不确定的,所以只能用动态列
        List<ToyDTO> toyDTOList = new ArrayList<>();
        toyDTOList.add(new ToyDTO("白雪公主","SnowWhite",1));
        toyDTOList.add(new ToyDTO("漫画书","Caricature",22));
        toyDTOList.add(new ToyDTO("乐高","Lego",3));
        toyDTOList.add(new ToyDTO("凹凸曼","Altman",0));
        toyDTOList.add(new ToyDTO("高达","Gundam",0));
        //构建多个学生和玩具的关系
        List<ExcelDTO> excelDTOList = new ArrayList<>();
        ExcelDTO excelDTO1 = new ExcelDTO("周老八",1,toyDTOList);
        ExcelDTO excelDTO2 = new ExcelDTO("李老八",2,toyDTOList);
        ExcelDTO excelDTO3 = new ExcelDTO("孙老八",3,toyDTOList);
        ExcelDTO excelDTO4 = new ExcelDTO("田老八",4,toyDTOList);
        excelDTOList.add(excelDTO1);
        excelDTOList.add(excelDTO2);
        excelDTOList.add(excelDTO3);
        excelDTOList.add(excelDTO4);
        //以上数据构建完毕,本质就是模拟从数据库中查询出来的数据。接下来是重点

		//1.构建列名
        //根据玩具列表动态构建列名(方法在下面)
        List<ExcelExportEntity> colList = addExcelCol(toyDTOList);
		
		//2.构建数据格式为Map
        //使用stream流(也可以用循环)将List中的对象修改成Map格式
        List<Map<String,Object>> ExcelDataMapList = excelDTOList.stream().map(data -> {
            Map<String,Object> dataMap = new HashMap<>();
            //将姓名和学号添加进去
            dataMap.put("studentName",data.getStudentName());
            dataMap.put("uid",data.getUid());
            //循环将玩具编码和数量放入map中
            data.getToyDTOList().forEach(toyDTO -> {
                dataMap.put(toyDTO.getToyCode(),toyDTO.getQuantity());
            });
            return dataMap;
        }).collect(Collectors.toList());

        //3.构建表格
        ExportParams exportParams = new ExportParams();
        exportParams.setType(ExcelType.XSSF);
        //构建工作薄(第二个参数是我们动态列的列表,第三个参数是Map的列表)
        Workbook workbook = ExcelExportUtil.exportExcel(exportParams, colList, ExcelDataMapList);
        String fileName = "学生拥有玩具数量.xlsx";
        //4.构建返回体
        try {
            response.setCharacterEncoding("UTF-8");
            response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
            response.setHeader("Content-disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8"));
            workbook.write(response.getOutputStream());
        } catch (IOException e) {
            throw new RuntimeException("Excel导出失败:" + e.getMessage());
        }


    }

    /**
     * 构建列名方法
     * @param toyDTOList
     * @return
     */
    public List<ExcelExportEntity> addExcelCol(List<ToyDTO> toyDTOList) {
        //表头的集合,用于添加表头
        List<ExcelExportEntity> entityList = new ArrayList<>();
        //1.可以自己写死列名,如下(第一个参数是列名,第二个参数是列的key,也就是controller里我们构建成Map的key,第三个参数是列的宽度)
        ExcelExportEntity channelOrgName = new ExcelExportEntity("学生名字", "studentName", 30);
        entityList.add(channelOrgName);
        
        ExcelExportEntity socialCreditCode = new ExcelExportEntity("学号", "uid", 30);
        entityList.add(socialCreditCode);
        //2.可以根据数据动态添加
        for(ToyDTO toyDTO : toyDTOList){
            ExcelExportEntity entity = new ExcelExportEntity(toyDTO.getToyName(),toyDTO.getToyCode(),30);
            entityList.add(entity);
        }
        return entityList;
    }
}

结果展示

image-20240507171258970

  • 4
    点赞
  • 5
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
首先,你需要在你的Spring Boot项目中添加Easypoi的依赖。可以在pom.xml中添加以下代码: ```xml <dependency> <groupId>cn.afterturn</groupId> <artifactId>easypoi-base</artifactId> <version>4.2.0</version> </dependency> ``` 接下来,你需要定义一个实体类作为导出的数据模型,并使用注解来定义每个字段的名称和格式。例如: ```java public class User { @Excel(name = "编号", orderNum = "0") private Integer id; @Excel(name = "用户名", orderNum = "1") private String username; @Excel(name = "注册时间", orderNum = "2", format = "yyyy-MM-dd HH:mm:ss") private Date createTime; // 省略getter和setter方法 } ``` 在上面的代码中,我们使用了@Excel注解来定义导出字段的名称、顺序和格式。其中,name属性指定了字段的名称,orderNum属性指定了字段在Excel文件中的顺序,format属性指定了时间字段的格式。 接下来,你可以在控制器中定义一个导出Excel文件的方法。例如: ```java @GetMapping("/export") public void export(HttpServletResponse response) throws IOException { List<User> userList = userService.getUserList(); // 定义导出的Excel文件名称 String fileName = "用户表.xlsx"; // 定义导出的数据表格 ExportParams exportParams = new ExportParams("用户表", "用户信息"); // 创建Excel文件并写入数据 Workbook workbook = ExcelExportUtil.exportExcel(exportParams, User.class, userList); // 设置响应头 response.setHeader("Content-Disposition", "attachment;filename=" + URLEncoder.encode(fileName, "UTF-8")); response.setContentType("application/vnd.ms-excel;charset=UTF-8"); // 将Excel文件写入响应输出流中 workbook.write(response.getOutputStream()); } ``` 在上面的代码中,我们使用Easypoi提供的ExcelExportUtil工具类来创建导出的Excel文件。其中,ExportParams对象用于定义导出文件的标题和表头,User.class用于定义数据模型,userList是要导出的数据集合。 最后,我们将Excel文件写入响应输出流中,以实现文件下载。 注意:如果你的时间字段是字符串类型,可以在导出时先将其转换为Date类型,然后再使用@Excel注解定义格式。例如: ```java public class User { @Excel(name = "编号", orderNum = "0") private Integer id; @Excel(name = "用户名", orderNum = "1") private String username; @Excel(name = "注册时间", orderNum = "2", format = "yyyy-MM-dd HH:mm:ss") private Date createTime; // 定义createTime的getter方法 public Date getCreateTime() { try { return new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").parse(this.createTime); } catch (ParseException e) { e.printStackTrace(); return null; } } // 定义createTime的setter方法 public void setCreateTime(String createTime) { this.createTime = createTime; } } ``` 在上面的代码中,我们将createTime字段从字符串类型转换为Date类型,并在getter方法中返回Date类型的值。这样,就可以使用@Excel注解定义时间格式了。

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值