java导出excel工具类~

又又优化了下以前写的工具类~


优点:

  1. 标题支持从实体类中直接取值
  2. 数据列表支持List<自定义类/八大基本类型/String>
  3. 工具类采用可变参数,不会过多限制数据数量与数据格式
  4. 数据列表中非自义定类支持多层嵌套List,比如List<List>,以后有空再改成能支持自义定类~
  5. 支持自义定要导出的字段,同时忽略序列化参数serialVersionUID

代码:

工具类:

package com.sk.financial.dg.supervision.util;

import cn.hutool.core.collection.CollUtil;
import com.sk.financial.dg.supervision.config.annotation.ExportDesc;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.core.annotation.AnnotationUtils;

import java.lang.reflect.Field;
import java.text.SimpleDateFormat;
import java.util.*;

public class DgExcelUtil {

    /**
     * 生成xlsx格式的Excel表格
     *
     * @param sheetName  sheet名称
     * @param titleClass 标题列表
     * @param exportList 要导出的自义定类里的字段名,为空时导出全部
     * @param data       数据列表,支持List<自定义类/八大基本类型/String>
     * @return XSSFWorkbook
     */
    public static XSSFWorkbook getXlsx(String sheetName,
                                       Class<?> titleClass, List<String> exportList, List<?>... data) throws IllegalAccessException {
        // 创建XSSFWorkbook对象
        XSSFWorkbook wb = new XSSFWorkbook();
        // 创建sheet对象
        XSSFSheet sheet = wb.createSheet(sheetName);
        // 在sheet里创建第一行,这里即是表头
        XSSFRow rowTitle = sheet.createRow(0);

        // 写入表头的每一个列
        List<String> titleList = DgExcelUtil.getTitleListByClass(titleClass, exportList);
        for (int i = 0; i < titleList.size(); i++) {
            // 创建单元格
            rowTitle.createCell(i).setCellValue(titleList.get(i));
        }

        // 写入每一行的记录
        int col = 1;
        for (List<?> dataList : data) {
            if (CollUtil.isEmpty(dataList)) {
                continue;
            }
            col = DgExcelUtil.setData(sheet, exportList, dataList, col);
        }
        return wb;
    }

    private static int setData(XSSFSheet sheet, List<String> exportList, List<?> dataList, int col) throws IllegalAccessException {
        if (dataList.get(0).getClass().equals(List.class)
                || dataList.get(0).getClass().toString().contains(Arrays.class.toString())
                || dataList.get(0).getClass().toString().contains(Collections.class.toString())){
            for (Object dataList2 : dataList) {
                if (CollUtil.isEmpty((List<?>) dataList2)) {
                    continue;
                }
                col = DgExcelUtil.setData(sheet, exportList, (List<?>) dataList2, col);
            }
            return col;
        }
        if (DgExcelUtil.isBaseType(dataList.get(0))) {
            // List<八大基本类型/String>创建新的一行
            XSSFRow rowData = sheet.createRow(col++);
            for (int j = 0, le = dataList.size(); j < le; j++) {
                //创建单元格
                Object obj = dataList.get(j);
                if (obj == null) {
                    continue;
                }
                rowData.createCell(j).setCellValue(String.valueOf(obj));
            }
        }
        else {
            // List<自定义类>创建多行
            for (Object o : dataList) {
                XSSFRow rowData = sheet.createRow(col++);
                Class<?> cl = o.getClass();
                Field[] fields = cl.getDeclaredFields();
                int j = 0;
                for (Field field : fields) {
                    // 忽略序列化参数或非导出列表里的参数
                    if ("serialVersionUID".equals(field.getName())) {
                        continue;
                    }
                    if (CollUtil.isNotEmpty(exportList) && !exportList.contains(field.getName())) {
                        continue;
                    }
                    // 设置字段可见,否则会报错,禁止访问
                    field.setAccessible(true);
                    // 创建单元格
                    Object obj = field.get(o);
                    if (obj == null) {
                        rowData.createCell(j).setCellValue("");
                    } else if (obj instanceof Date) {
                        rowData.createCell(j).setCellValue(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss").format(obj));
                    } else {
                        rowData.createCell(j).setCellValue(String.valueOf(obj));
                    }
                    j++;
                }
            }
        }
        return col;
    }

    /**
     * 用反射获取Desc注释值,来生成标题列表titleList
     *
     * @param titleClass
     * @param <T>
     * @return
     */
    public static <T> List<String> getTitleListByClass(Class<T> titleClass, List<String> exportList) {
        List<String> titleList = new ArrayList<>();
        Field[] titleFields = titleClass.getDeclaredFields();
        for (Field field : titleFields) {
            if (CollUtil.isNotEmpty(exportList) && !exportList.contains(field.getName())) {
                continue;
            }
            ExportDesc desc = AnnotationUtils.findAnnotation(field, ExportDesc.class);
            if (desc != null) {
                titleList.add(desc.value());
            }
        }
        return titleList;
    }

    /**
     * 将List<?>转换为List<T>
     *
     * @param obj
     * @param clazz
     * @param <T>
     * @return
     */
    public static <T> List<T> castList(Object obj, Class<T> clazz) {
        List<T> result = new ArrayList<>();
        if (obj instanceof List<?>) {
            for (Object o : (List<?>) obj) {
                result.add(clazz.cast(o));
            }
            return result;
        }
        return null;
    }

    /**
     * 判断object是否为基本类型或String
     *
     * @param object
     * @return
     */
    public static boolean isBaseType(Object object) {
        Class<?> className = object.getClass();
        return (className.equals(Integer.class) ||
                className.equals(Byte.class) ||
                className.equals(Long.class) ||
                className.equals(Double.class) ||
                className.equals(Float.class) ||
                className.equals(Character.class) ||
                className.equals(Short.class) ||
                className.equals(Boolean.class) ||
                className.equals(String.class));
    }
}

调用接口:

http://localhost:8080/excel/getExcel
posted @ 2022-07-06 15:09  一语子  阅读(566)  评论(0)    收藏  举报