当前位置:网站首页>EasyExcel根据筛选列导出(中间不空列,顺序可调整)

EasyExcel根据筛选列导出(中间不空列,顺序可调整)

2020-11-09 16:11:00 T小豆芽

使用EasyExel根据筛选列导出的方式在官方文档就有一个“根据参数只导出指定列”的例子,但这个例子我测了一下导出来的Excel是这样的。

EasyExcel官方文档:https://www.yuque.com/easyexcel/doc

“名字”和“生日”中间这里却空出来了一列,但如果按前端显示了哪些字段才需要进行导出,而且顺序也要按前端展示的一样(前端实现了拖拽还有筛选指定显示哪些字段,因此导出的格式也要一致...),这个官方文档给出的例子似乎不太满足,于是我写了一个利用不创建对象+反射的方式实现的例子。

这是我写的一个Person测试对象

public class Person {

    @ExcelIgnore
    private Long id;

    @ExcelProperty("名字")
    private String name;

    @ExcelProperty("年龄")
    private int age;

    @ExcelProperty("生日")
    @DateTimeFormat("yyyy年MM月dd日")
    private Date birthday;

    public Long getId() {
        return id;
    }

    public void setId(Long id) {
        this.id = id;
    }

    public String getName() {
        return name;
    }

    public void setName(String name) {
        this.name = name;
    }

    public int getAge() {
        return age;
    }

    public void setAge(int age) {
        this.age = age;
    }

    public Date getBirthday() {
        return birthday;
    }

    public void setBirthday(Date birthday) {
        this.birthday = birthday;
    }
}

使用官方文档的“不创建对象的写”的例子,封装一下,使用反射将需要筛选的字段返回

package com.example.demo.utils;

import com.alibaba.excel.EasyExcel;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.lang.reflect.Method;
import java.util.ArrayList;
import java.util.List;

/**
 * @author 小豆芽
 * @version 1.0
 * @Date 2020-11-09 09:13
 */
public class EasyExcelUtils {
    private static final Logger logger = LoggerFactory.getLogger(EasyExcelUtils.class);

    /**
     * @param fileName  文件路径名
     * @param sheetName sheet名
     * @param data      查询出来的数据
     * @param headList  传入的Excel头(例如:姓名,生日)
     * @param fileList  传入需要展示的字段(例如:姓名对应字段是name,生日对应字段是birthday)
     */
    public static void noModelWrite(String fileName, String sheetName, List data, List<String> headList, List<String> fileList){
        EasyExcel.write(fileName).head(head(headList)).sheet(sheetName).doWrite(dataList(data,fileList));
    }

    /**
     * 设置Excel头
     * @param headList  Excel头信息
     * @return
     */
    private static List<List<String>> head(List<String> headList) {
        List<List<String>> list = new ArrayList<>();

        for (String value : headList) {
            List<String> head = new ArrayList<>();
            head.add(value);
            list.add(head);
        }
        return list;
    }

    /**
     * 设置表格信息
     * @param dataList  查询出的数据
     * @param fileList  需要显示的字段
     * @return
     */
    private static List<List<Object>> dataList(List<Object> dataList, List<String> fileList) {
        List<List<Object>> list = new ArrayList<>();
        for (Object person : dataList) {
            List<Object> data = new ArrayList<>();
            for (String fieldName : fileList) {
                /**通过反射根据需要显示的字段,获取对应的属性值*/
                data.add(getFieldValue(fieldName, person));
            }
            list.add(data);
        }
        return list;
    }

    /**
     * 根据传入的字段获取对应的get方法,如name,对应的getName方法
     * @param fieldName  字段名
     * @param person    对象
     * @return
     */
    private static Object getFieldValue(String fieldName, Object person) {
        try {

            String firstLetter = fieldName.substring(0, 1).toUpperCase();
            String getter = "get" + firstLetter + fieldName.substring(1);
            Method method = person.getClass().getMethod(getter);
            return method.invoke(person);
        } catch (Exception e) {
            logger.error("使用反射获取对象属性值失败", e);
            return null;
        }

    }


}

controller层使用该工具类进行写Excel。

@RequestMapping(value = "/auth/downloadList",method = {RequestMethod.GET, RequestMethod.POST})
    public void downloadList(String filedNames,String filedCodes){
        List<Person> list = personServiceImpl.findPersonAll();

        /**Excel头,参数格式:姓名,生日*/
        String[] head = filedNames.split(",");
        List<String> headList = new ArrayList<>(Arrays.asList(head));

        /**Excel表格内容,参数格式:name,birthday*/
        String[] file = filedCodes.split(",");
        List<String> fileList = new ArrayList<>(Arrays.asList(file));

        EasyExcelUtils.noModelWrite("E:/data/测试例子.xls","测试例子",list,headList,fileList);
    }

测试1传入参数为:

filedNames名字,生日

filedCodesname,birthday

效果如下:

测试2传入参数为:

filedNames :  生日,名字

filedCodesbirthday,name

效果如下:

通过上面的代码,使用EasyExcel的不创建对象写+反射技术可以实现不会空出一列或多列的Excel,并且可以根据前端传入参数的顺序实现动态列展示。

注意:

1. 使用这种方式需要传入Excel表头信息和对应的字段信息;

2. 因为使用的是利用反射调用属性名对应的get方法来获取值,需要查看属性对应的get方法是否命名规范,如果不规范则需要另行处理。

 

版权声明
本文为[T小豆芽]所创,转载请带上原文链接,感谢
https://my.oschina.net/zjiamin/blog/4710076