springboot整合easyexcel进行动态表头导出

简介

在企业的开发工程中,偶尔会遇到不同的用户具有不同表头的结构的导出功能实现,这个时候,使用类添加注解,然后进行映射的方式可能无法实现,那么这种时候只能自己写一下表头映射了。
本案例基于EasyExcel实现了LinkedHashMap进行字段、表头、默认值的映射,从而达到动态导出数据的功能,测试以实际场景中,编写controller接口导出接口,希望能够帮助到你!

1、引入easyExcel依赖

        <dependency>
            <groupId>com.alibabagroupId>
            <artifactId>easyexcelartifactId>
            <version>3.0.5version>
        dependency>

尽量引入高版本的easyexcel,2.x的版本可能会有坑

2、引入映射类

package com.walker.entity;

import lombok.Data;

@Data
public class DynamicExcelData {
    //列名
    private String name;
    //默认值
    private String defaultValue;

    public DynamicExcelData(String name, String defaultValue) {
        this.name = name;
        this.defaultValue = defaultValue;
    }
}

3、导出方法



public static void dynamicExport(HttpServletResponse response,
                                 LinkedHashMap<String,DynamicExcelData> nameMap,
                                 List<Map<String, Object>> list,
                                 String sheetName) throws IOException {
    //首先判断是否有数据,没有就返回
    if(CollUtil.isEmpty(list)){
        return;
    }

    //这里的map使用LinkedHashMap,实现字段的顺序功能
    if(nameMap==null){
        throw new RuntimeException("请填写好映射表数据");
    }

	//先初始化一下传入
    int size = list.size();
    List<List<String>> dataList = new ArrayList<>();
    for (int i = 0; i < size; i++) {
        dataList.add(new ArrayList<>());
    }

    //获取表头
    ArrayList<List<String>> head = new ArrayList<>();
    for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {
        DynamicExcelData data = titleMap.getValue();
        head.add(Collections.singletonList(data.getName()));
    }

    //数据重组
    for (int i = 0; i < list.size(); i++) {
        Map<String, Object> map = list.get(i);
        List<String> columns = dataList.get(i);
        for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {
            String key = sortNameEntry.getKey();
            Object value = map.get(key);
            columns.add(value!=null?String.valueOf(value):sortNameEntry.getValue().getDefaultValue());
        }
    }

    response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
    response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
    response.setCharacterEncoding("utf-8");

    //使用EasyExcel write进行写出
    EasyExcel.write(response.getOutputStream()).head(head)
        .sheet(sheetName).doWrite(dataList);
}

4、测试接口编写

package com.walker.controller;

import cn.hutool.core.collection.CollUtil;
import com.alibaba.excel.EasyExcel;
import com.walker.entity.DynamicExcelData;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import javax.servlet.http.HttpServletResponse;
import java.io.IOException;
import java.util.*;

@RestController
@RequestMapping("/export")
public class ExportController {


    @PostMapping("/export")
    public void export(HttpServletResponse response) throws IOException {

        //模拟数据
        //一般动态数据使用的是List,然后内部使用Map进行数据的接受
        List<Map<String, Object>> list = new ArrayList<>();
        for (int i = 0; i < 10; i++) {
            HashMap<String, Object> map = new HashMap<>();
            for (int j = 0; j < 5; j++) {
                map.put("title"+j,i+","+j);
            }
            //这个用于测试值如果为null时,能否进行默认值填充
            map.put("title5",null);
            list.add(map);
        }


        //使用LinkedHashMap进行表头字段映射
        LinkedHashMap<String, DynamicExcelData> nameMap = new LinkedHashMap<>();
        nameMap.put("title1",new DynamicExcelData("年龄","0"));
        nameMap.put("title0",new DynamicExcelData("姓名","0"));
        nameMap.put("title2",new DynamicExcelData("职业","0"));
        nameMap.put("title3",new DynamicExcelData("爱好","0"));
        nameMap.put("title4",new DynamicExcelData("小名","0"));
        nameMap.put("title5",new DynamicExcelData("空白字段","0"));

        //调用方法,方法已在步骤3进行介绍
        dynamicExport(response,nameMap, list,"模板");

    }


    /**
    * 列表
    */
    public static void dynamicExport(HttpServletResponse response,
                                     LinkedHashMap<String,DynamicExcelData> nameMap,
                                     List<Map<String, Object>> list,
                                     String sheetName) throws IOException {
        if(CollUtil.isEmpty(list)){
            return;
        }
        if(nameMap==null){
            throw new RuntimeException("请填写好映射表数据");
        }

        int size = list.size();
        List<List<String>> dataList = new ArrayList<>();
        for (int i = 0; i < size; i++) {
            dataList.add(new ArrayList<>());
        }

        //获取表头
        ArrayList<List<String>> head = new ArrayList<>();
        for (Map.Entry<String, DynamicExcelData> titleMap : nameMap.entrySet()) {
            DynamicExcelData data = titleMap.getValue();
            head.add(Collections.singletonList(data.getName()));
        }

        //数据重组
        for (int i = 0; i < list.size(); i++) {
            Map<String, Object> map = list.get(i);
            List<String> columns = dataList.get(i);
            for (Map.Entry<String, DynamicExcelData> sortNameEntry : nameMap.entrySet()) {
                String key = sortNameEntry.getKey();
                Object value = map.get(key);
                columns.add(value!=null?String.valueOf(value):sortNameEntry.getValue().getDefaultValue());
            }

        }

        response.setHeader("Access-Control-Expose-Headers", "Content-Disposition");
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");

        EasyExcel.write(response.getOutputStream()).head(head)
                .sheet(sheetName).doWrite(dataList);
    }
}

5、接口调用

我使用的是apiPost,这里就不细讲了
调用的方式很多,可以使用Postman,也可以让前端进行调用。
直接看看返回结果
springboot整合easyexcel进行动态表头导出_第1张图片

  • 空白字段,全部结果都进行了补"0"操作
  • 根据LinkedHashMap定义的顺序,可以发现年龄放在了前面,姓名在后

springboot整合easyexcel进行动态表头导出_第2张图片

总结

这个也算是简陋的实现方式了,希望能够帮助到你!
我是walker,欢迎关注公众号I am Walker,有更多的干货分享~

你可能感兴趣的:(springboot系列,spring,boot,后端,java)