动态数据导出【自定义注解】

本文介绍了如何在Java项目中使用EasyExcel库结合自定义注解,实现数据导出功能,包括自定义注解的定义、工具类对类操作的方法以及实例应用。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

自定义注解实现数据导出

  1. 导入easyexcle依赖
    <dependency>
      <groupId>com.alibaba</groupId>
      <artifactId>easyexcel</artifactId>
      <version>2.2.10</version>
    </dependency>
  1. 自定义注解

@FiledName
作用在实体类,表明字段变量对应中文

import java.lang.annotation.ElementType;
import java.lang.annotation.Retention;
import java.lang.annotation.RetentionPolicy;
import java.lang.annotation.Target;

// 自定义注解
@Target(ElementType.FIELD)
@Retention(RetentionPolicy.RUNTIME)
public @interface FieldName {
    String value() default "名字";
}
  1. 工具类

ClassUtils
对类进行操作,获取属性列表名称

import export_excel.FieldName;
import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

/**
 * 对类的操作
 */
public class ClassUtils {

    /**
     * 通过类型返回对应的属性列表
     * @param target 目标类型
     * @return 属性列表
     */
    public static List<String> getFields(Class<?> target) {
        // 获取所有成员变量名称
        List<String> fieldList = new ArrayList<>();
        Field[] declaredFields = target.getDeclaredFields();

        // 放入 List 集合中
        for(Field field : declaredFields) {
            fieldList.add(field.getName());
        }

        return  fieldList;
    }

    /**
     * 获取泛型所有的成员及其值的映射
     * @param data 泛型对象
     * @param <T> 泛型
     * @return 成员变量名和成员变量值的映射
     */
    public static <T> Map<String, Object> getFieldOfValue(T data) throws IllegalAccessException {
        // 获取所有成员变量,并建立一个 Map(大小为成员变量的个数)来存放名字和值的对应关系
        Field[] declaredFields = data.getClass().getDeclaredFields();
        Map<String, Object> fieldMap = new HashMap<>(declaredFields.length);

        // 获取每个成员属性对应的值,并映射
        for (Field field : declaredFields) {
            // 允许访问私有变量的值
            field.setAccessible(true);
            String fieldData=null;
            if(field.get(data)==null){
                fieldData="";
            }else{
                fieldData = field.get(data).toString();
            }
            // 获取属性值,并在其为空时赋予默认值
//            String fieldData = field.get(data).toString();
//            fieldData = fieldData == null ? "": fieldData;
            // 获取成员变量的值,并放入 map 中
            fieldMap.put(field.getName(), fieldData);
        }

        return fieldMap;
    }

    /**
     * 通过类型返回对应的属性名称列表
     * 名称为该属性上的 FieldName(自定义注解) 的值
     * @param target 目标类型
     * @return 属性对应的中文名称列表
     */
    public static List<String> getFieldNames(Class<?> target) {
        // 获取所有成员变量名称
        List<String> fieldList = new ArrayList<>();
        Field[] declaredFields = target.getDeclaredFields();

        // 放入 List 集合中
        for(Field field : declaredFields) {

            // 获取该成员变量注解 FieldName 的值,即其对应的中文名称
            // 这里通过反射,取出了属性中的 value 值,即属性对象的中文名称
            fieldList.add(field.getAnnotation(FieldName.class).value());
        }

        return  fieldList;
    }

}
  1. 数据导出公用Service

ExportExcelService
整合

import export_excel.util.ClassUtils;
import org.apache.poi.hssf.usermodel.*;
import org.apache.poi.ss.usermodel.HorizontalAlignment;
import javax.servlet.ServletOutputStream;
import java.io.IOException;
import java.util.List;
import java.util.Map;

public class ExportExcelService {
    /**
     * 将列表数据导出为 Excel 表格
     * @param dataList 列表数据
     * @param out 输出源
     * @param <T> 数据的类型
     */
    public static <T> void exportExcel(List<T> dataList, ServletOutputStream out) throws IllegalAccessException, IOException {
        // 空集合直接返回
        if (dataList.isEmpty()) {
            return;
        }

        // 获取泛型 T 的所有成员变量
        // 这里的第一种是获取原属性名,第二种是获取属性对应的注解 FieldName 的值,即对应的中文名称
        List<String> fieldList = ClassUtils.getFields(dataList.get(0).getClass());
        List<String> fieldNameList = ClassUtils.getFieldNames(dataList.get(0).getClass());

        // 建立一个 Excel 文件,并在文件中创建一个表单
        HSSFWorkbook workbook = new HSSFWorkbook(); // 用于创建.xlsx文件
        HSSFSheet sheet = workbook.createSheet();

        // 创建行(表头)
        HSSFRow row = sheet.createRow(0);

        // 创建单元格,并设置表头居中
        HSSFCellStyle xssfCellStyle = workbook.createCellStyle();
        xssfCellStyle.setAlignment(HorizontalAlignment.CENTER);

        // 循环设置列名(这里使用注解对应的中文名)
        HSSFCell xssfCell;
        for (int i = 0; i < fieldNameList.size(); i++) {
            xssfCell = row.createCell(i);
            xssfCell.setCellValue(fieldNameList.get(i));
            xssfCell.setCellStyle(xssfCellStyle);
        }

        // 为每一行添加数据
        Map<String, Object> dataMap;
        for (int i = 0; i < dataList.size(); i++) {
            // 添加新的一行
            row = sheet.createRow(i + 1);

            // 获取泛型对象 T 的成员变量和值的对应关系
            dataMap = ClassUtils.getFieldOfValue(dataList.get(i));

            // 将数据写入该行
            for (int j = 0; j < fieldList.size(); j++) {
                // 先通过 list 获取成员变量名,再通过 map 获取对应的值,转化为 String 之后放入表格中
                row.createCell(j).setCellValue("" + dataMap.get(fieldList.get(j)));
            }
        }

        // 将数据输出,刷出,关闭
        workbook.write(out);
        out.flush();;
        out.close();
    }

}
  1. 实例使用

(1)VO中使用自定义注解

    @FieldName("问题id")
    private Integer questionId;
    @FieldName("具体问题")
    private String question;

(2)controller中实现数据导出

 	/**
     * 数据导出
     */
    @ResponseBody
    public RespResult downExcel (HttpServletResponse response, @RequestBody SelectDTO selectDTO) throws IOException, IllegalAccessException {
        // 设置 ContentType 和返回头
        response.setContentType("application/binary;charset=UTF-8");
        response.setHeader("Content-Disposition", "attachment; fileName=" + URLEncoder.encode("问题清单数据"+new SimpleDateFormat("yyyyMMddHHmmss").format(new Date()) +".xls", "UTF-8"));
        //获得输出流
        ServletOutputStream out = response.getOutputStream();
        // 制造数据
        List<SelectVO> list = service.selectList(selectDTO);
        // 输出 excel 表格数据
        ExportExcelService.exportExcel(list, out);
        return RespResult.success();
    }

【注意: 导出的Excel是.xls还是.xlsx,其具体配置不一样,如果不注意打开导出的Excel文件时会报错格式不匹配】

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值