EasyExcel数据导出功能封装

起因:

最近需要用到excel导出功能,使用EasyExcel可以快速实现导出,又需要优雅的对EasyExcel进行封装,在实现自己的导出功能时又可以制定一定的规则,让其他同事方便使用,最近研究了下网上的常规写法,站在巨人的肩上重新添加了自己的思路,供大家参考,有任何问题请多指教

痛点:

1、导出代码写在业务中,调用不统一且代码层次混乱
2、数据库查询的数据远多于对象中定义的数据,导出时默认导出了不想要的数据
3、相同的对象,在导出时需要根据不同条件进行设置不同的Excel表头字段,又不想定义多个导出对象
4、导出时如果设置过某个属性的表头宽度,优先按照设置的宽度导出,如果未设置,希望表头宽度有个默认值,而不是挤压在一起
5、excel需要导出大数据,都在一个sheet页中查看卡顿
6、导出的数据是数据库字符,查看excel人员看不懂,需要做数据转化

如果你有以上痛点问题,可以继续啦;如果没有也可以看看我的封装思路,还请各位高手不吝赐教,这里非常感谢 雪孤城的这篇文章 给了我很大的启发和参考

1. 工具类

1.1 EasyExcelUtil封装类

package cn.well.cloud.core.util.excel;

import cn.hutool.core.date.DatePattern;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import com.alibaba.excel.EasyExcel;
import com.alibaba.excel.ExcelWriter;
import com.alibaba.excel.write.builder.ExcelWriterSheetBuilder;
import com.alibaba.excel.write.metadata.WriteSheet;
import lombok.extern.slf4j.Slf4j;
import org.springframework.web.context.request.RequestContextHolder;
import org.springframework.web.context.request.ServletRequestAttributes;


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

/**
 * @Description: Easyexcel工具类封装及表格自动列宽设置
 * @Author: jiawei
 * @Date: 2023/7/26
 */
@Slf4j
public class EasyExcelUtil {

    /**
     * 每个sheet的容量,即超过60000时就会把数据分sheet
     */
    private static final int PAGE_SIZE = 60000;

    /**
     * 无过滤字段的导出excel
     * @param data 需要导出的数据集
     * @param fileName 需要导出的excel名
     * @param excelClass 需要导出的excel表头实体
     * @return
     * @author jiawei
     * @since 2023/7/27 下午1:39
     */
    public static void exportByExcel(List<?> data, String fileName, Class<?> excelClass){
        exportByExcel(data, fileName, excelClass, AbstractEasyExcel.getExcludeColumnFieldNames());
    }
    
    /**
     *  自定义过滤字段的导出excel
     * @param data 需要导出的数据集
     * @param fileName 需要导出的excel名
     * @param excelClass 需要导出的excel表头实体
     * @param excludeColumnFieldNames 需要过滤的字段集合
     * @return 
     * @author jiawei
     * @since 2023/7/27 下午1:41
     */
    public static void exportByExcel(List<?> data, String fileName, Class<?> excelClass, Collection<String> excludeColumnFieldNames){
        try {
            ServletRequestAttributes servletRequestAttributes = (ServletRequestAttributes) RequestContextHolder.getRequestAttributes();
            HttpServletResponse response = servletRequestAttributes.getResponse();
            long exportStartTime = System.currentTimeMillis();;
            log.info("报表导出Size: " + data.size() + "条。");
            // 把查询到的数据按设置的sheet的容量进行切割
            List<? extends List<?>> lists = SplitList.splitList(data, PAGE_SIZE);
            // 设置响应头
            AbstractEasyExcel.setHead(response, fileName + DateUtil.format(new Date(), DatePattern.PURE_DATETIME_PATTERN));
            // 浏览器访问url直接下载文件的方式
            ExcelWriter excelWriter = EasyExcel.write(response.getOutputStream(), excelClass)
                    .registerWriteHandler(AbstractEasyExcel.formatExcel())
                    .registerWriteHandler(new AbstractEasyExcel.ExcelWidthStyleStrategy())
                    .includeColumnFieldNames(AbstractEasyExcel.getIncludeColumnFiledNames(excelClass))
                    .excludeColumnFieldNames(excludeColumnFieldNames)
                    .build();

            ExcelWriterSheetBuilder excelWriterSheetBuilder;
            WriteSheet writeSheet;
            if(ObjectUtil.hasNull(lists)){
                log.info("未查询到要导出的数据,导出终止");
                return;
            }
            for (int i = 1; i <= lists.size(); ++i) {
                excelWriterSheetBuilder = new ExcelWriterSheetBuilder(excelWriter);
                excelWriterSheetBuilder.sheetNo(i).sheetName("sheet" + i);
                writeSheet = excelWriterSheetBuilder.build();
                excelWriter.write(lists.get(i - 1), writeSheet);
            }
            // 必须要finish才会写入,不finish只会创建empty的文件
            excelWriter.finish();
            log.info("报表导出结束时间:" + new Date() + ";导出耗时: " + (System.currentTimeMillis() - exportStartTime) + "ms");

        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

1.2AbstractEasyExcel EasyExcel的基础封装,包含响应头设置,Excel的格式设置,根据实体设置需要导出的字段,设置需要过滤的实体中字段(字符串模式和lambda表达获取get方法引用的属性+连续方法调用模式),设置头部单元格宽度
AbstractEasyExcel

package cn.well.cloud.core.util.excel;

import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.metadata.Head;
import com.alibaba.excel.metadata.data.WriteCellData;
import com.alibaba.excel.write.metadata.holder.WriteSheetHolder;
import com.alibaba.excel.write.metadata.style.WriteCellStyle;
import com.alibaba.excel.write.metadata.style.WriteFont;
import com.alibaba.excel.write.style.HorizontalCellStyleStrategy;
import com.alibaba.excel.write.style.column.AbstractColumnWidthStyleStrategy;
import com.baomidou.mybatisplus.core.toolkit.ExceptionUtils;
import com.baomidou.mybatisplus.core.toolkit.support.SFunction;
import lombok.extern.slf4j.Slf4j;
import org.apache.poi.ss.usermodel.*;

import javax.servlet.http.HttpServletResponse;
import java.io.UnsupportedEncodingException;
import java.lang.reflect.Field;
import java.net.URLEncoder;
import java.util.*;

/**
 * @Description: EasyExcel的基础封装
 * @Author: jiawei
 * @Date: 2023/7/26
 */
@Slf4j
public class AbstractEasyExcel {

    /**
     * 设置响应头
     *
     * @param response 回应的请求数据
     * @param fileName 文件名字
     */
    public static void setHead(HttpServletResponse response, String fileName) {

        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet");
        response.setCharacterEncoding("utf-8");
        // 这里URLEncoder.encode可以防止中文乱码
        try {
            fileName = URLEncoder.encode(fileName, "UTF-8").replaceAll("\\+", "%20");
        } catch (UnsupportedEncodingException e) {
            e.printStackTrace();
            log.error("编码异常");
        }
        response.setHeader("Content-disposition", "attachment;filename*=utf-8''" + fileName + ".xlsx");

    }

    /**
     * 设置Excel的格式
     *
     * @return 格式化后的Excel
     */
    public static HorizontalCellStyleStrategy formatExcel() {
        WriteCellStyle headWriteCellStyle = new WriteCellStyle();
        headWriteCellStyle.setFillBackgroundColor(IndexedColors.WHITE.getIndex());
        WriteFont headWriteFont = new WriteFont();
        headWriteFont.setFontHeightInPoints((short) 10);
        headWriteCellStyle.setWriteFont(headWriteFont);
        // 内容的策略
        WriteCellStyle contentWriteCellStyle = new WriteCellStyle();
        WriteFont contentWriteFont = new WriteFont();
        // 字体大小
        contentWriteFont.setFontHeightInPoints((short) 10);
        contentWriteCellStyle.setWriteFont(contentWriteFont);
        // 设置自动换行
        contentWriteCellStyle.setWrapped(true);
        // 设置垂直居中
        contentWriteCellStyle.setVerticalAlignment(VerticalAlignment.CENTER);
        // 设置水平居中
        contentWriteCellStyle.setHorizontalAlignment(HorizontalAlignment.CENTER);

        return new HorizontalCellStyleStrategy(headWriteCellStyle, contentWriteCellStyle);

    }


    /**
     * 设置需要导出的字段
     * @param clazz
     * @return {@link Integer}
     * @author jiawei
     * @since 2023/7/27 上午11:21
     */
    public static Collection<String> getIncludeColumnFiledNames(Class<?> clazz) {
        Set<String> set = new HashSet<String>();
        Field[]     fields;
        do {
            fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                set.add(fields[i].getName());
            }
            clazz = clazz.getSuperclass();
        } while (clazz != Object.class && clazz != null);
        return set;
    }

    /**
     * 设置需要过滤的字段方式一(不推荐)
     * @param fields 字段名
     * @return {@link Collection< String>}
     * @author jiawei
     * @since 2023/7/27 下午1:32
     */
    public static Collection<String> getExcludeColumnFieldNames(Object ... fields) {
        Set<String> excludeColumnFieldNames = new HashSet<String>();

        for (Object field : fields) {
            excludeColumnFieldNames.add(StrUtil.toString(field));
        }
        return excludeColumnFieldNames;
    }

    /**
     * 设置需要过滤的字段方式二(推荐)
     * @param excludeColumn
     * @return {@link Collection< String>}
     * @author jiawei
     * @since 2023/7/27 下午2:57
     */
    public static Collection<String> getExcludeColumnFieldNames(ExcludeColumn excludeColumn) {
        return excludeColumn.excludeColumnFieldNames;
    }


    public static class ExcludeColumn{
        Set<String> excludeColumnFieldNames = new HashSet<String>();

        public  <T> ExcludeColumn add(SFunction<T, ?> fn) {
            String field= FieldUtil.getField(fn).getName();
            if (field instanceof String) {
                excludeColumnFieldNames.add(StrUtil.toString(field));
                return this;
            }
            throw ExceptionUtils.mpe("not support this column :" + field);
        }
    }


    /**
     * 获取class的 包括父类的
     *
     * @param clazz
     * @return
     */
    public static Field[] getClassFields(Class<?> clazz) {
        List<Field> list = new ArrayList<Field>();
        Field[]     fields;
        do {
            fields = clazz.getDeclaredFields();
            for (int i = 0; i < fields.length; i++) {
                list.add(fields[i]);
            }
            clazz = clazz.getSuperclass();
        } while (clazz != Object.class && clazz != null);
        return list.toArray(fields);
    }

    /**
     * 设置头部单元格宽度
     */
    public static class ExcelWidthStyleStrategy extends AbstractColumnWidthStyleStrategy {
        
        /**
         * 设置列表,默认50
         * @param writeSheetHolder
         * @param list
         * @param cell
         * @param head
         * @param relativeRowIndex
         * @param isHead
         * @return 
         * @author jiawei
         * @since 2023/7/27 上午10:52
         */
        @Override
        protected void setColumnWidth(WriteSheetHolder writeSheetHolder, List<WriteCellData<?>> list, Cell cell, Head head, Integer relativeRowIndex, Boolean isHead) {
            Sheet sheet = writeSheetHolder.getSheet();

            boolean needSetWidth = relativeRowIndex != null && (isHead || relativeRowIndex == 0);
            if (!needSetWidth) {
                return;
            }
            Integer width = columnWidth(head, cell.getColumnIndex());
            if (width != null) {
                width = width * 256;
                sheet.setColumnWidth(cell.getColumnIndex(), width);
            }else{
                sheet.setColumnWidth(cell.getColumnIndex(), 5000);
            }
        }


        /**
         * 获取设置的自定义宽度
         * @param head
         * @param columnIndex
         * @return {@link java.lang.Integer}
         * @author jiawei
         * @since 2023/7/27 上午10:50
         */
        protected Integer columnWidth(Head head, Integer columnIndex) {
            if (head == null) {
                return null;
            } else {
                return head.getColumnWidthProperty() != null ? head.getColumnWidthProperty().getWidth() : null;
            }
        }
    }
}

1.3 getField bean属性获取工具类,此工具中使用可序列化的 SFunction,引用的是mybatisplus 核心包底下现成的,当然你如果未引用mybatisplus 的话,也可以自己添加上该类,非常简单,附在该工具类后面了

package cn.well.cloud.core.util.excel;

import com.baomidou.mybatisplus.core.toolkit.support.SFunction;

import java.lang.invoke.SerializedLambda;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
/**
 * @Description: bean属性获取工具类
 * @Author: jiawei
 * @Date: 2023/7/27
 */
public class FieldUtil {
    /**
     * 将bean的属性的get方法,作为lambda表达式传入时,获取get方法对应的属性Field
     *
     * @param fn  lambda表达式,bean的属性的get方法
     * @param <T> 泛型
     * @return 属性对象
     */
    public static <T> Field getField(SFunction<T, ?> fn) {
        // 从function取出序列化方法
        Method writeReplaceMethod;
        try {
            writeReplaceMethod = fn.getClass().getDeclaredMethod("writeReplace");
        } catch (NoSuchMethodException e) {
            throw new RuntimeException(e);
        }

        // 从序列化方法取出序列化的lambda信息
        boolean isAccessible = writeReplaceMethod.isAccessible();
        writeReplaceMethod.setAccessible(true);
        SerializedLambda serializedLambda;
        try {
            serializedLambda = (SerializedLambda) writeReplaceMethod.invoke(fn);
        } catch (IllegalAccessException | InvocationTargetException e) {
            throw new RuntimeException(e);
        }
        writeReplaceMethod.setAccessible(isAccessible);

        // 从lambda信息取出method、field、class等
        String implMethodName = serializedLambda.getImplMethodName();
        // 确保方法是符合规范的get方法,boolean类型是is开头
        if (!implMethodName.startsWith("is") && !implMethodName.startsWith("get")) {
            throw new RuntimeException("get方法名称: " + implMethodName + ", 不符合java bean规范");
        }

        // get方法开头为 is 或者 get,将方法名 去除is或者get,然后首字母小写,就是属性名
        int prefixLen = implMethodName.startsWith("is") ? 2 : 3;

        String fieldName = implMethodName.substring(prefixLen);
        String firstChar = fieldName.substring(0, 1);
        fieldName = fieldName.replaceFirst(firstChar, firstChar.toLowerCase());
        Field field;
        try {
            field = Class.forName(serializedLambda.getImplClass().replace("/", ".")).getDeclaredField(fieldName);
        } catch (ClassNotFoundException | NoSuchFieldException e) {
            throw new RuntimeException(e);
        }

        return field;
    }
}

1.3.1 SFunction 对,你没看错,就是一个空的接口类

package com.baomidou.mybatisplus.core.toolkit.support;

import java.io.Serializable;
import java.util.function.Function;

/**
 * 支持序列化的 Function
 *
 * @author miemie
 * @since 2018-05-12
 */
@FunctionalInterface
public interface SFunction<T, R> extends Function<T, R>, Serializable {
}

1.4 SplitList EasyExcelUtils类的辅助类(切割查询的数据)

package cn.well.cloud.core.util.excel;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * @Description: EasyExcelUtils类的辅助类(切割查询的数据)
 * @Author: jiawei
 * @Date: 2023/7/26
 */
public class SplitList {
    /**
     * 切割查询的数据
     * @param list 需要切割的数据
     * @param len 按照什么长度切割
     * @param <T>
     * @return
     */
    public static <T> List<List<T>> splitList(List<T> list, int len) {
        if (list == null || list.size() == 0 || len < 1) {
            return null;
        }
        List<List<T>> result = new ArrayList<List<T>>();
        int size = list.size();
        int count = (size + len - 1) / len;
        for (int i = 0; i < count; i++) {
            List<T> subList = list.subList(i * len, (Math.min((i + 1) * len, size)));
            result.add(subList);
        }
        return result;
    }

    /**
     * 集合平均分组
     * @param source 源集合
     * @param n 分成n个集合
     * @param <T> 集合类型
     * @return 平均分组后的集合
     */
    public static <T> List<List<T>> groupList(List<T> source, int n) {
        if (source == null || source.size() == 0 || n < 1) {
            return null;
        }
        if (source.size() < n) {
            return Collections.singletonList(source);
        }
        List<List<T>> result = new ArrayList<List<T>>();
        int number = source.size() / n;
        int remaider = source.size() % n;
        // 偏移量,每有一个余数分配,就要往右偏移一位
        int offset = 0;
        for (int i = 0; i < n;i++) {
            List<T> list1 = null;
            if (remaider > 0){
                list1 = source.subList(i * number + offset,(i + 1) * number + offset + 1);
                remaider--;
                offset++;
            }else {
                list1 = source.subList(i * number + offset, (i+1) * number + offset);
            }
            result.add(list1);
        }
        return result;
    }
}

数据转换工具

2.1 AbstactBaseConverter 抽象类,自定义的类只需要实现该类即可

package cn.well.cloud.core.util.excel.converter;

import com.alibaba.excel.converters.Converter;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.enums.CellDataTypeEnum;
import com.alibaba.excel.metadata.data.WriteCellData;

/**
 * @Description:
 * @Author: jiawei
 * @Date: 2023/7/27
 */
public class AbstactBaseConverter implements Converter<String> {
    @Override
    public Class<?> supportJavaTypeKey() {
        return String.class;
    }

    @Override
    public CellDataTypeEnum supportExcelTypeKey() {
        return CellDataTypeEnum.STRING;
    }

    /**
     * 这里读的时候会调用
     * @param context
     * @return {@link java.lang.String}
     * @author jiawei
     * @since 2023/7/27 上午9:47
     */
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        return context.getReadCellData().getStringValue();
    }

    /**
     * 这里是写的时候会调用
     * @param context
     * @return {@link com.alibaba.excel.metadata.data.WriteCellData<?>}
     * @author jiawei
     * @since 2023/7/27 上午9:47
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        return new WriteCellData<>(context.getValue());
    }
}

2.2 YesOrNotConverter自定义某个字段值导出时,“Y"导出"是”,“N"导出"否”

package cn.well.cloud.core.util.excel.converter;

import cn.well.cloud.core.enums.YesOrNotEnum;
import com.alibaba.excel.converters.ReadConverterContext;
import com.alibaba.excel.converters.WriteConverterContext;
import com.alibaba.excel.metadata.data.WriteCellData;

/**
 * @Description:
 * @Author: jiawei
 * @Date: 2023/7/27
 */
public class YesOrNotConverter extends  AbstactBaseConverter {
    /**
     * 重写读方法
     * @param context
     * @return {@link java.lang.String}
     * @author jiawei
     * @since 2023/7/27 上午9:46
     */
    @Override
    public String convertToJavaData(ReadConverterContext<?> context) {
        return super.convertToJavaData(context);
    }

    /**
     * 重写写方法
     * @param context
     * @return {@link com.alibaba.excel.metadata.data.WriteCellData<?>}
     * @author jiawei
     * @since 2023/7/27 上午9:47
     */
    @Override
    public WriteCellData<?> convertToExcelData(WriteConverterContext<String> context) {
        return new WriteCellData<>( YesOrNotEnum.N.getCode().equals(context.getValue())? YesOrNotEnum.N.getMessage():YesOrNotEnum.Y.getMessage() );
    }

}

2.3 YesOrNotEnum 枚举类

package cn.well.cloud.core.enums;

import lombok.Getter;

/**
 * 是或否的枚举
 *
 * @Author: jiawei
 * @Date: 2023/7/27
 */
@Getter
public enum YesOrNotEnum {

    /**
     * 是
     */
    Y("Y",1, "是"),

    /**
     * 否
     */
    N("N",0, "否");

    private final String code;

    private final int value;

    private final String message;

    YesOrNotEnum(String code,Integer value, String message) {
        this.code = code;
        this.value = value;
        this.message = message;
    }

}

以上是基础工具的封装,大家可以写到底层包里,供业务层调用,我的目录格式如下
在这里插入图片描述
业务层
3.1 EapCardNumBo 导出对象

package cn.well.cloud.modular.eap.contract.card.bo;

import cn.well.cloud.core.util.excel.converter.YesOrNotConverter;
import com.alibaba.excel.annotation.ExcelProperty;
import com.alibaba.excel.annotation.format.DateTimeFormat;
import com.alibaba.excel.annotation.write.style.ColumnWidth;
import com.alibaba.excel.annotation.write.style.ContentStyle;
import lombok.Data;
import lombok.EqualsAndHashCode;

import java.io.Serializable;
import java.util.Date;

/**
 * @Description:  卡号表
 * @author jaiwei
 * @since 2023-07-23
 */
@Data
@EqualsAndHashCode
public class EapCardNumBo implements Serializable {

      @ExcelProperty(value = "序号")
      private Integer serialNumber;

      @ExcelProperty(value = "合同唯一标识")
      @ContentStyle(dataFormat = 1)
      @ColumnWidth(80)
      private Long contractUid;

      @ExcelProperty(value = "卡号")
      private String cardNumber;

      @ExcelProperty(value = "是否绑定", converter = YesOrNotConverter.class)
      private String hasBinding;

      @ExcelProperty(value = "卡号类型")
      private Integer cardType;

      @ExcelProperty(value = "创建时间")
      @DateTimeFormat("yyyy-MM-dd hh:mm:ss")
      private Date createTime;

}

3.2 调用方法,此处是业务层方法中的调用方式,mybatisplus查询数据的代码就补贴出来了

@Override
public void export(Long contractUid) {
    List<EapCardNumPO> eapCardNumPOList = baseEapCardNumMapper.selectList(new QueryWrapperX<EapCardNumPO>().lambda().eq(EapCardNumPO::getContractUid, contractUid));
    //调用方式一(推荐)
    AbstractEasyExcel.ExcludeColumn excludeColumn = new AbstractEasyExcel.ExcludeColumn().add(EapCardNumBo::getContractUid).add(EapCardNumBo::getCreateTime);
    EasyExcelUtil.exportByExcel(eapCardNumPOList,"卡号",EapCardNumBo.class, AbstractEasyExcel.getExcludeColumnFieldNames(excludeColumn));
	
	//调用方式二(不推荐)
    EasyExcelUtil.exportByExcel(eapCardNumPOList,"卡号",EapCardNumBo.class, AbstractEasyExcel.getExcludeColumnFieldNames("contractUid","createTime"));

}

总结如下

新增工具类
EasyExcelUtil excel读写工具类
具体实现方法
exportByExcel() 浏览器直接导出

自定义导出实体注解

@ContentStyle 设置数据格式,dataFormat = 1 会避免较长数字科学计数法显示,其他格式参见easyexcel-core包底下的com.alibaba.excel.constant.BuiltinFormats
converter = YesOrNotConverter.class 自定义转换导出的内容,比如Y需要导出是,N需要导出否,不建议在数据和业务层面进行处理,而是抽取出转换器类进行处理
@DateTimeFormat 时间格式化
@ColumnWidth(80) 该注解不添加,默认单元格宽度是50,超过50长度时需要自定义列宽

方法调用一(推荐)

AbstractEasyExcel.ExcludeColumn excludeColumn = new AbstractEasyExcel.ExcludeColumn().add(EapCardNumBo::getContractUid).add(EapCardNumBo::getCreateTime);
EasyExcelUtil.exportByExcel(eapCardNumPOList,"卡号",EapCardNumBo.class, AbstractEasyExcel.getExcludeColumnFieldNames(excludeColumn));

`
方法调用二(不推荐)

EasyExcelUtil.exportByExcel(eapCardNumPOList,"卡号",EapCardNumBo.class, AbstractEasyExcel.getExcludeColumnFieldNames("contractUid","createTime"));

非常感谢阿里巴巴对EasyExcel的开源,且用且珍惜

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
EasyExcel是一个Java库,用于在Excel文件中进行读写操作。在使用EasyExcel进行导出时,可以使用实体封装的方式。首先,需要创建一个实体类,例如TrafficExcelResponse,该类中定义了要导出的字段,并使用注解进行配置,如@ExcelProperty用于指定Excel中的列名,@ColumnWidth用于指定列宽度等。然后,将要导出数据封装到一个List中。最后,使用EasyExcelUtil.writeExcel方法进行导出,该方法接收导出的文件名、sheet名、实体类等参数。\[2\] 另外,如果需要支持用户自定义导出字段,可以在请求头中添加TITLE_NAME和FIELD_NAME参数,参数值以英文逗号分隔,并保证一一对应。这样可以实现根据用户选择导出指定的字段。\[3\] 总结起来,使用EasyExcel进行导出封装的步骤如下: 1. 创建导出的实体类,并使用注解进行配置。 2. 将要导出数据封装到List中。 3. 调用EasyExcelUtil.writeExcel方法进行导出,传入导出的文件名、sheet名、实体类等参数。 4. 如果需要支持用户自定义导出字段,可以在请求头中添加TITLE_NAME和FIELD_NAME参数,参数值以英文逗号分隔,并保证一一对应。 #### 引用[.reference_title] - *1* [EasyExcel 导入导出封装工具](https://blog.csdn.net/fzy629442466/article/details/126382299)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *2* [Alibaba easyexcel导出使用和工具封装](https://blog.csdn.net/orange_bug/article/details/126834569)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] - *3* [集成easyexcel自定义封装,全局通用导出excel功能](https://blog.csdn.net/Lee_SmallNorth/article/details/128338510)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^control_2,239^v3^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值