alibaba.excel库使用

目录

依赖

实体类

Controller

Service

所用到的接口及工具类

 ExcelUtil

 ExcelListener

 DefaultExcelListener

 DefaultExcelResult

 ExcelResult

 JsonUtils

 SpringUtils

 StreamUtils

 ValidatorUtils

 SpringUtils


使用alibab中的excel库来实现excel的导入、导出

依赖

        
            org.apache.poi
            poi
            5.2.3
        
        
            org.apache.poi
            poi-ooxml
            5.2.3
        
        
            com.alibaba
            easyexcel
            3.2.1
            
                
                    org.apache.poi
                    poi-ooxml-schemas
                
            
        

实体类

@ExcelProperty、@ExcelIgnoreUnannotated注解

import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import com.ict.lux.core.domain.BaseEntity;
import lombok.Data;
import lombok.NoArgsConstructor;

import javax.validation.constraints.NotBlank;


@Data
@NoArgsConstructor
@ExcelIgnoreUnannotated
public class BaseProductStackImportVo extends BaseEntity {

    private static final long serialVersionUID = 4732391370534949564L;

    /**
     * 编码
     */
    @NotBlank(message = "编码不能为空")
    @ExcelProperty(value = "编码")
    private String stackNo;

    /**
     * 名称
     */
    @NotBlank(message = "名称不能为空")
    @ExcelProperty(value = "名称")
    private String stackName;

}



===================================================================================



import com.alibaba.excel.annotation.ExcelIgnoreUnannotated;
import com.alibaba.excel.annotation.ExcelProperty;
import lombok.Data;

import java.time.LocalDateTime;



@Data
@ExcelIgnoreUnannotated
public class BaseProductStackVo {

    /**
     * id
     */
    private int id;

    /**
     * 编码
     */
    @ExcelProperty(value = "编码")
    private String stackNo;

    /**
     * 名称
     */
    @ExcelProperty(value = "名称")
    private String stackName;

    /**
     * 创建时间
     */
    @ExcelProperty(value = "创建时间")
    private LocalDateTime createTime;

    /**
     * 创建人姓名
     */
    @ExcelProperty(value = "创建人")
    private String createName;

    /**
     * 更新时间
     */
    @ExcelProperty(value = "更新时间")
    private LocalDateTime updateTime;

    /**
     * 更新人姓名
     */
    @ExcelProperty(value = "更新人")
    private String updateName;

}

Controller

    /**
     * 导入数据
     *
     * @param file 导入文件
     */
    @PostMapping(value = "/importData", consumes = MediaType.MULTIPART_FORM_DATA_VALUE)
    public R importData(@RequestPart("file") MultipartFile file) throws Exception {
        ExcelResult excelResult = ExcelUtil.importExcel(file.getInputStream(), BaseProductStackImportVo.class, true);
        List volist = excelResult.getList();
        List list = BeanUtil.copyToList(volist, BaseProductStackEntity.class);
        baseProductStackService.importBatch(list);
        return R.ok(excelResult.getAnalysis());
    }



    /**
     * 导出
     */
    @PostMapping("/export")
    public void export(@Validated(QueryGroup.class) BaseProductStackBo baseBo, HttpServletResponse response) {
        List list = baseProductStackService.queryAll(baseBo);
        ExcelUtil.exportExcel(list, "123信息", BaseProductStackVo.class, response);
    }



    /**
     * 下载导入模版
     */
    @PostMapping("/template")
    public void template(HttpServletResponse response) {
        List list = new ArrayList<>();
        ExcelUtil.exportExcel(list, "123信息导入模板", BaseProductStackImportVo.class, response);
    }

Service

    /**
     * 批量导入
     */
    void importBatch(List importData);


    /**
     * 查询全部信息
     */
    List queryAll(BaseProductStackBo baseBo);


   /**
    * 批量导入
    */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void importBatch(List importData) {

        List saveOrUpdateList = new ArrayList<>();

        //验证是否有重复
        List duplicates = new ArrayList<>();

        importData.forEach(data -> {
            String duplicate = String.join(PlmConstants.Underline, data.getStackNo());
            if (duplicates.contains(duplicate)) {
                throw new QMSException("导入的123信息重复,请检查:" + data.getStackNo());
            }

            duplicates.add(duplicate);

            BaseProductStackEntity baseProductStackEntity = this.findOne(data.getStackNo());
            if (ObjectUtil.isNotNull(baseProductStackEntity)) {
                BeanUtil.copyProperties(data, baseProductStackEntity, CopyOptions.create().setIgnoreNullValue(true));
                saveOrUpdateList.add(baseProductStackEntity);
            } else {
                saveOrUpdateList.add(data);
            }
        });

        baseMapper.insertOrUpdateBatch(saveOrUpdateList);
        saveOrUpdateList.forEach(entity -> {
            RedisUtils.setCacheObject(buildRedisKey(entity.getStackNo()), entity);
        });
    }


   /**
    * 导出
    */
    @Override
    public List queryAll(BaseProductStackBo baseBo) {
        //select * from xxx
        return baseMapper.customQueryList(baseBo);

    }


所用到的接口及工具类

 ExcelUtil

@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ExcelUtil {

    /**
     * 同步导入(适用于小数据量)
     *
     * @param is 输入流
     * @return 转换后集合
     */
    public static  List importExcel(InputStream is, Class clazz) {
        return EasyExcel.read(is).head(clazz).autoCloseStream(false).sheet().doReadSync();
    }


    /**
     * 使用校验监听器 异步导入 同步返回
     *
     * @param is         输入流
     * @param clazz      对象类型
     * @param isValidate 是否 Validator 检验 默认为是
     * @return 转换后集合
     */
    public static  ExcelResult importExcel(InputStream is, Class clazz, boolean isValidate) {
        DefaultExcelListener listener = new DefaultExcelListener<>(isValidate);
        EasyExcel.read(is, clazz, listener).sheet().doRead();
        return listener.getExcelResult();
    }

    /**
     * 使用自定义监听器 异步导入 自定义返回
     *
     * @param is       输入流
     * @param clazz    对象类型
     * @param listener 自定义监听器
     * @return 转换后集合
     */
    public static  ExcelResult importExcel(InputStream is, Class clazz, ExcelListener listener) {
        EasyExcel.read(is, clazz, listener).sheet().doRead();
        return listener.getExcelResult();
    }

    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param response  响应体
     */
    public static  void exportExcel(List list, String sheetName, Class clazz, HttpServletResponse response) {
        try {
            resetResponse(sheetName, response);
            ServletOutputStream os = response.getOutputStream();
            exportExcel(list, sheetName, clazz, false, os);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel异常");
        }
    }

    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param merge     是否合并单元格
     * @param response  响应体
     */
    public static  void exportExcel(List list, String sheetName, Class clazz, boolean merge, HttpServletResponse response) {
        try {
            resetResponse(sheetName, response);
            ServletOutputStream os = response.getOutputStream();
            exportExcel(list, sheetName, clazz, merge, os);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel异常");
        }
    }

    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param os        输出流
     */
    public static  void exportExcel(List list, String sheetName, Class clazz, OutputStream os) {
        exportExcel(list, sheetName, clazz, false, os);
    }

    /**
     * 导出excel
     *
     * @param list      导出数据集合
     * @param sheetName 工作表的名称
     * @param clazz     实体类
     * @param merge     是否合并单元格
     * @param os        输出流
     */
    public static  void exportExcel(List list, String sheetName, Class clazz, boolean merge, OutputStream os) {
        ExcelWriterSheetBuilder builder = EasyExcel.write(os, clazz)
            .autoCloseStream(false)
            // 自动适配
            .registerWriteHandler(new LongestMatchColumnWidthStyleStrategy())
            // 大数值自动转换 防止失真
            .registerConverter(new ExcelBigNumberConvert())
            .sheet(sheetName);
        if (merge) {
            // 合并处理器
            builder.registerWriteHandler(new CellMergeStrategy(list, true));
        }
        builder.doWrite(list);
    }

    /**
     * 单表多数据模板导出 模板格式为 {.属性}
     *
     * @param filename     文件名
     * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
     *                     例如: excel/temp.xlsx
     *                     重点: 模板文件必须放置到启动类对应的 resource 目录下
     * @param data         模板需要的数据
     * @param response     响应体
     */
    public static void exportTemplate(List data, String filename, String templatePath, HttpServletResponse response) {
        try {
            resetResponse(filename, response);
            ServletOutputStream os = response.getOutputStream();
            exportTemplate(data, templatePath, os);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel异常");
        }
    }

    /**
     * 单表多数据模板导出 模板格式为 {.属性}
     *
     * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
     *                     例如: excel/temp.xlsx
     *                     重点: 模板文件必须放置到启动类对应的 resource 目录下
     * @param data         模板需要的数据
     * @param os           输出流
     */
    public static void exportTemplate(List data, String templatePath, OutputStream os) {
        ClassPathResource templateResource = new ClassPathResource(templatePath);
        ExcelWriter excelWriter = EasyExcel.write(os)
            .withTemplate(templateResource.getStream())
            .autoCloseStream(false)
            // 大数值自动转换 防止失真
            .registerConverter(new ExcelBigNumberConvert())
            .build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        if (CollUtil.isEmpty(data)) {
            throw new IllegalArgumentException("数据为空");
        }
        // 单表多数据导出 模板格式为 {.属性}
        for (Object d : data) {
            excelWriter.fill(d, writeSheet);
        }
        excelWriter.finish();
    }

    /**
     * 多表多数据模板导出 模板格式为 {key.属性}
     *
     * @param filename     文件名
     * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
     *                     例如: excel/temp.xlsx
     *                     重点: 模板文件必须放置到启动类对应的 resource 目录下
     * @param data         模板需要的数据
     * @param response     响应体
     */
    public static void exportTemplateMultiList(Map data, String filename, String templatePath, HttpServletResponse response) {
        try {
            resetResponse(filename, response);
            ServletOutputStream os = response.getOutputStream();
            exportTemplateMultiList(data, templatePath, os);
        } catch (IOException e) {
            throw new RuntimeException("导出Excel异常");
        }
    }

    /**
     * 多表多数据模板导出 模板格式为 {key.属性}
     *
     * @param templatePath 模板路径 resource 目录下的路径包括模板文件名
     *                     例如: excel/temp.xlsx
     *                     重点: 模板文件必须放置到启动类对应的 resource 目录下
     * @param data         模板需要的数据
     * @param os           输出流
     */
    public static void exportTemplateMultiList(Map data, String templatePath, OutputStream os) {
        ClassPathResource templateResource = new ClassPathResource(templatePath);
        ExcelWriter excelWriter = EasyExcel.write(os)
            .withTemplate(templateResource.getStream())
            .autoCloseStream(false)
            // 大数值自动转换 防止失真
            .registerConverter(new ExcelBigNumberConvert())
            .build();
        WriteSheet writeSheet = EasyExcel.writerSheet().build();
        if (CollUtil.isEmpty(data)) {
            throw new IllegalArgumentException("数据为空");
        }
        for (Map.Entry map : data.entrySet()) {
            // 设置列表后续还有数据
            FillConfig fillConfig = FillConfig.builder().forceNewRow(Boolean.TRUE).build();
            if (map.getValue() instanceof Collection) {
                // 多表导出必须使用 FillWrapper
                excelWriter.fill(new FillWrapper(map.getKey(), (Collection) map.getValue()), fillConfig, writeSheet);
            } else {
                excelWriter.fill(map.getValue(), writeSheet);
            }
        }
        excelWriter.finish();
    }

    /**
     * 重置响应体
     */
    private static void resetResponse(String sheetName, HttpServletResponse response) throws UnsupportedEncodingException {
        String filename = encodingFilename(sheetName);
        FileUtils.setAttachmentResponseHeader(response, filename);
        response.setContentType("application/vnd.openxmlformats-officedocument.spreadsheetml.sheet;charset=UTF-8");
    }

    /**
     * 解析导出值 0=男,1=女,2=未知
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public static String convertByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(StringUtils.SEPARATOR);
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[0].equals(value)) {
                        propertyString.append(itemArray[1] + separator);
                        break;
                    }
                }
            } else {
                if (itemArray[0].equals(propertyValue)) {
                    return itemArray[1];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 反向解析值 男=0,女=1,未知=2
     *
     * @param propertyValue 参数值
     * @param converterExp  翻译注解
     * @param separator     分隔符
     * @return 解析后值
     */
    public static String reverseByExp(String propertyValue, String converterExp, String separator) {
        StringBuilder propertyString = new StringBuilder();
        String[] convertSource = converterExp.split(StringUtils.SEPARATOR);
        for (String item : convertSource) {
            String[] itemArray = item.split("=");
            if (StringUtils.containsAny(propertyValue, separator)) {
                for (String value : propertyValue.split(separator)) {
                    if (itemArray[1].equals(value)) {
                        propertyString.append(itemArray[0] + separator);
                        break;
                    }
                }
            } else {
                if (itemArray[1].equals(propertyValue)) {
                    return itemArray[0];
                }
            }
        }
        return StringUtils.stripEnd(propertyString.toString(), separator);
    }

    /**
     * 编码文件名
     */
    public static String encodingFilename(String filename) {
        return IdUtil.fastSimpleUUID() + "_" + filename + ".xlsx";
    }

} 
  

 ExcelListener

import com.alibaba.excel.read.listener.ReadListener;

/**
 * Excel 导入监听
 *
 * @author chensir
 */
public interface ExcelListener extends ReadListener {

    ExcelResult getExcelResult();

}

 DefaultExcelListener



import cn.hutool.core.util.StrUtil;
import com.alibaba.excel.context.AnalysisContext;
import com.alibaba.excel.event.AnalysisEventListener;
import com.alibaba.excel.exception.ExcelAnalysisException;
import com.alibaba.excel.exception.ExcelDataConvertException;
import com.ict.lux.utils.JsonUtils;
import com.ict.lux.utils.StreamUtils;
import com.ict.lux.utils.ValidatorUtils;
import lombok.NoArgsConstructor;
import lombok.extern.slf4j.Slf4j;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import java.util.Map;
import java.util.Set;

/**
 * Excel 导入监听
 *
 * @author chensir
 */
@Slf4j
@NoArgsConstructor
public class DefaultExcelListener extends AnalysisEventListener implements ExcelListener {

    /**
     * 是否Validator检验,默认为是
     */
    private Boolean isValidate = Boolean.TRUE;

    /**
     * excel 表头数据
     */
    private Map headMap;

    /**
     * 导入回执
     */
    private ExcelResult excelResult;

    public DefaultExcelListener(boolean isValidate) {
        this.excelResult = new DefaultExcelResult<>();
        this.isValidate = isValidate;
    }

    /**
     * 处理异常
     *
     * @param exception ExcelDataConvertException
     * @param context   Excel 上下文
     */
    @Override
    public void onException(Exception exception, AnalysisContext context) throws Exception {
        String errMsg = null;
        if (exception instanceof ExcelDataConvertException) {
            // 如果是某一个单元格的转换异常 能获取到具体行号
            ExcelDataConvertException excelDataConvertException = (ExcelDataConvertException) exception;
            Integer rowIndex = excelDataConvertException.getRowIndex();
            Integer columnIndex = excelDataConvertException.getColumnIndex();
            errMsg = StrUtil.format("第{}行-第{}列-表头{}: 解析异常
", rowIndex + 1, columnIndex + 1, headMap.get(columnIndex)); if (log.isDebugEnabled()) { log.error(errMsg); } } if (exception instanceof ConstraintViolationException) { ConstraintViolationException constraintViolationException = (ConstraintViolationException) exception; Set> constraintViolations = constraintViolationException.getConstraintViolations(); String constraintViolationsMsg = StreamUtils.join(constraintViolations, ConstraintViolation::getMessage, ", "); errMsg = StrUtil.format("第{}行数据校验异常: {}", context.readRowHolder().getRowIndex() + 1, constraintViolationsMsg); if (log.isDebugEnabled()) { log.error(errMsg); } } excelResult.getErrorList().add(errMsg); throw new ExcelAnalysisException(errMsg); } @Override public void invokeHeadMap(Map headMap, AnalysisContext context) { this.headMap = headMap; log.debug("解析到一条表头数据: {}", JsonUtils.toJsonString(headMap)); } @Override public void invoke(T data, AnalysisContext context) { if (isValidate) { ValidatorUtils.validate(data); } excelResult.getList().add(data); } @Override public void doAfterAllAnalysed(AnalysisContext context) { log.debug("所有数据解析完成!"); } @Override public ExcelResult getExcelResult() { return excelResult; } }

 DefaultExcelResult

import cn.hutool.core.util.StrUtil;
import lombok.Setter;

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

/**
 * 默认excel返回对象
 *
 * @author chensir
 */
public class DefaultExcelResult implements ExcelResult {

    /**
     * 数据对象list
     */
    @Setter
    private List list;

    /**
     * 错误信息列表
     */
    @Setter
    private List errorList;

    public DefaultExcelResult() {
        this.list = new ArrayList<>();
        this.errorList = new ArrayList<>();
    }

    public DefaultExcelResult(List list, List errorList) {
        this.list = list;
        this.errorList = errorList;
    }

    public DefaultExcelResult(ExcelResult excelResult) {
        this.list = excelResult.getList();
        this.errorList = excelResult.getErrorList();
    }

    @Override
    public List getList() {
        return list;
    }

    @Override
    public List getErrorList() {
        return errorList;
    }

    /**
     * 获取导入回执
     *
     * @return 导入回执
     */
    @Override
    public String getAnalysis() {
        int successCount = list.size();
        int errorCount = errorList.size();
        if (successCount == 0) {
            return "读取失败,未解析到数据";
        } else {
            if (errorCount == 0) {
                return StrUtil.format("恭喜您,全部读取成功!共{}条", successCount);
            } else {
                return "";
            }
        }
    }
}

 ExcelResult

/**
 * excel返回对象
 *
 * @author chensir
 */
public interface ExcelResult {

    /**
     * 对象列表
     */
    List getList();

    /**
     * 错误列表
     */
    List getErrorList();

    /**
     * 导入回执
     */
    String getAnalysis();
}

 JsonUtils

import cn.hutool.core.lang.Dict;
import cn.hutool.core.util.ArrayUtil;
import cn.hutool.core.util.ObjectUtil;
import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.core.type.TypeReference;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.exc.MismatchedInputException;
import com.ict.lux.utils.spring.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.io.IOException;
import java.util.ArrayList;
import java.util.List;

/**
 * JSON 工具类
 *
 * @author chensir
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class JsonUtils {

    private static final ObjectMapper OBJECT_MAPPER = SpringUtils.getBean(ObjectMapper.class);

    public static ObjectMapper getObjectMapper() {
        return OBJECT_MAPPER;
    }

    public static String toJsonString(Object object) {
        if (ObjectUtil.isNull(object)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.writeValueAsString(object);
        } catch (JsonProcessingException e) {
            throw new RuntimeException(e);
        }
    }

    public static  T parseObject(String text, Class clazz) {
        if (StringUtils.isEmpty(text)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(text, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static  T parseObject(byte[] bytes, Class clazz) {
        if (ArrayUtil.isEmpty(bytes)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(bytes, clazz);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static  T parseObject(String text, TypeReference typeReference) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(text, typeReference);
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static Dict parseMap(String text) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructType(Dict.class));
        } catch (MismatchedInputException e) {
            // 类型不匹配说明不是json
            return null;
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static List parseArrayMap(String text) {
        if (StringUtils.isBlank(text)) {
            return null;
        }
        try {
            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, Dict.class));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

    public static  List parseArray(String text, Class clazz) {
        if (StringUtils.isEmpty(text)) {
            return new ArrayList<>();
        }
        try {
            return OBJECT_MAPPER.readValue(text, OBJECT_MAPPER.getTypeFactory().constructCollectionType(List.class, clazz));
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
    }

}

 SpringUtils

package com.ict.lux.utils.spring;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * spring工具类
 *
 * @author chensir
 */
@Component
public final class SpringUtils extends SpringUtil {

    /**
     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
     *
     * @param name
     * @return boolean
     */
    public static boolean containsBean(String name) {
        return getBeanFactory().containsBean(name);
    }

    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
     * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     *
     * @param name
     * @return boolean
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().isSingleton(name);
    }

    /**
     * @param name
     * @return Class 注册对象的类型
     */
    public static Class getType(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().getType(name);
    }

    /**
     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
     *
     * @param name
     */
    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().getAliases(name);
    }

    /**
     * 获取aop代理对象
     *
     * @param invoker
     * @return
     */
    @SuppressWarnings("unchecked")
    public static  T getAopProxy(T invoker) {
        return (T) AopContext.currentProxy();
    }


    /**
     * 获取spring上下文
     */
    public static ApplicationContext context() {
        return getApplicationContext();
    }

}

 StreamUtils

package com.ict.lux.utils;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.map.MapUtil;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import java.util.*;
import java.util.function.BiFunction;
import java.util.function.Function;
import java.util.function.Predicate;
import java.util.stream.Collectors;

/**
 * stream 流工具类
 *
 * @author chensir
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class StreamUtils {

    /**
     * 将collection过滤
     *
     * @param collection 需要转化的集合
     * @param function   过滤方法
     * @return 过滤后的list
     */
    public static  List filter(Collection collection, Predicate function) {
        if (CollUtil.isEmpty(collection)) {
            return CollUtil.newArrayList();
        }
        return collection.stream().filter(function).collect(Collectors.toList());
    }

    /**
     * 将collection拼接
     *
     * @param collection 需要转化的集合
     * @param function   拼接方法
     * @return 拼接后的list
     */
    public static  String join(Collection collection, Function function) {
        return join(collection, function, StringUtils.SEPARATOR);
    }

    /**
     * 将collection拼接
     *
     * @param collection 需要转化的集合
     * @param function   拼接方法
     * @param delimiter  拼接符
     * @return 拼接后的list
     */
    public static  String join(Collection collection, Function function, CharSequence delimiter) {
        if (CollUtil.isEmpty(collection)) {
            return StringUtils.EMPTY;
        }
        return collection.stream().map(function).filter(Objects::nonNull).collect(Collectors.joining(delimiter));
    }

    /**
     * 将collection排序
     *
     * @param collection 需要转化的集合
     * @param comparing  排序方法
     * @return 排序后的list
     */
    public static  List sorted(Collection collection, Comparator comparing) {
        if (CollUtil.isEmpty(collection)) {
            return CollUtil.newArrayList();
        }
        return collection.stream().sorted(comparing).collect(Collectors.toList());
    }

    /**
     * 将collection转化为类型不变的map
* {@code Collection ----> Map} * * @param collection 需要转化的集合 * @param key V类型转化为K类型的lambda方法 * @param collection中的泛型 * @param map中的key类型 * @return 转化后的map */ public static Map toIdentityMap(Collection collection, Function key) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(); } return collection.stream().collect(Collectors.toMap(key, Function.identity(), (l, r) -> l)); } /** * 将Collection转化为map(value类型与collection的泛型不同)
* {@code Collection -----> Map } * * @param collection 需要转化的集合 * @param key E类型转化为K类型的lambda方法 * @param value E类型转化为V类型的lambda方法 * @param collection中的泛型 * @param map中的key类型 * @param map中的value类型 * @return 转化后的map */ public static Map toMap(Collection collection, Function key, Function value) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(); } return collection.stream().collect(Collectors.toMap(key, value, (l, r) -> l)); } /** * 将collection按照规则(比如有相同的班级id)分类成map
* {@code Collection -------> Map> } * * @param collection 需要分类的集合 * @param key 分类的规则 * @param collection中的泛型 * @param map中的key类型 * @return 分类后的map */ public static Map> groupByKey(Collection collection, Function key) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(); } return collection .stream() .collect(Collectors.groupingBy(key, LinkedHashMap::new, Collectors.toList())); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
* {@code Collection ---> Map>> } * * @param collection 需要分类的集合 * @param key1 第一个分类的规则 * @param key2 第二个分类的规则 * @param 集合元素类型 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @return 分类后的map */ public static Map>> groupBy2Key(Collection collection, Function key1, Function key2) { if (CollUtil.isEmpty(collection)) { return MapUtil.newHashMap(); } return collection .stream() .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.groupingBy(key2, LinkedHashMap::new, Collectors.toList()))); } /** * 将collection按照两个规则(比如有相同的年级id,班级id)分类成双层map
* {@code Collection ---> Map> } * * @param collection 需要分类的集合 * @param key1 第一个分类的规则 * @param key2 第二个分类的规则 * @param 第一个map中的key类型 * @param 第二个map中的key类型 * @param collection中的泛型 * @return 分类后的map */ public static Map> group2Map(Collection collection, Function key1, Function key2) { if (CollUtil.isEmpty(collection) || key1 == null || key2 == null) { return MapUtil.newHashMap(); } return collection .stream() .collect(Collectors.groupingBy(key1, LinkedHashMap::new, Collectors.toMap(key2, Function.identity(), (l, r) -> l))); } /** * 将collection转化为List集合,但是两者的泛型不同
* {@code Collection ------> List } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为list泛型的lambda表达式 * @param collection中的泛型 * @param List中的泛型 * @return 转化后的list */ public static List toList(Collection collection, Function function) { if (CollUtil.isEmpty(collection)) { return CollUtil.newArrayList(); } return collection .stream() .map(function) .filter(Objects::nonNull) .collect(Collectors.toList()); } /** * 将collection转化为Set集合,但是两者的泛型不同
* {@code Collection ------> Set } * * @param collection 需要转化的集合 * @param function collection中的泛型转化为set泛型的lambda表达式 * @param collection中的泛型 * @param Set中的泛型 * @return 转化后的Set */ public static Set toSet(Collection collection, Function function) { if (CollUtil.isEmpty(collection) || function == null) { return CollUtil.newHashSet(); } return collection .stream() .map(function) .filter(Objects::nonNull) .collect(Collectors.toSet()); } /** * 合并两个相同key类型的map * * @param map1 第一个需要合并的 map * @param map2 第二个需要合并的 map * @param merge 合并的lambda,将key value1 value2合并成最终的类型,注意value可能为空的情况 * @param map中的key类型 * @param 第一个 map的value类型 * @param 第二个 map的value类型 * @param 最终map的value类型 * @return 合并后的map */ public static Map merge(Map map1, Map map2, BiFunction merge) { if (MapUtil.isEmpty(map1) && MapUtil.isEmpty(map2)) { return MapUtil.newHashMap(); } else if (MapUtil.isEmpty(map1)) { map1 = MapUtil.newHashMap(); } else if (MapUtil.isEmpty(map2)) { map2 = MapUtil.newHashMap(); } Set key = new HashSet<>(); key.addAll(map1.keySet()); key.addAll(map2.keySet()); Map map = new HashMap<>(); for (K t : key) { X x = map1.get(t); Y y = map2.get(t); V z = merge.apply(x, y); if (z != null) { map.put(t, z); } } return map; } }

 ValidatorUtils

package com.ict.lux.utils;

import com.ict.lux.utils.spring.SpringUtils;
import lombok.AccessLevel;
import lombok.NoArgsConstructor;

import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;
import javax.validation.Validator;
import java.util.Set;

/**
 * Validator 校验框架工具
 *
 * @author chensir
 */
@NoArgsConstructor(access = AccessLevel.PRIVATE)
public class ValidatorUtils {

    private static final Validator VALID = SpringUtils.getBean(Validator.class);

    public static  void validate(T object, Class... groups) {
        Set> validate = VALID.validate(object, groups);
        if (!validate.isEmpty()) {
            throw new ConstraintViolationException("参数校验异常", validate);
        }
    }

}

 SpringUtils

package com.ict.lux.utils.spring;

import cn.hutool.extra.spring.SpringUtil;
import org.springframework.aop.framework.AopContext;
import org.springframework.beans.factory.NoSuchBeanDefinitionException;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;

/**
 * spring工具类
 *
 * @author chensir
 */
@Component
public final class SpringUtils extends SpringUtil {

    /**
     * 如果BeanFactory包含一个与所给名称匹配的bean定义,则返回true
     *
     * @param name
     * @return boolean
     */
    public static boolean containsBean(String name) {
        return getBeanFactory().containsBean(name);
    }

    /**
     * 判断以给定名字注册的bean定义是一个singleton还是一个prototype。
     * 如果与给定名字相应的bean定义没有被找到,将会抛出一个异常(NoSuchBeanDefinitionException)
     *
     * @param name
     * @return boolean
     */
    public static boolean isSingleton(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().isSingleton(name);
    }

    /**
     * @param name
     * @return Class 注册对象的类型
     */
    public static Class getType(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().getType(name);
    }

    /**
     * 如果给定的bean名字在bean定义中有别名,则返回这些别名
     *
     * @param name
     */
    public static String[] getAliases(String name) throws NoSuchBeanDefinitionException {
        return getBeanFactory().getAliases(name);
    }

    /**
     * 获取aop代理对象
     *
     * @param invoker
     * @return
     */
    @SuppressWarnings("unchecked")
    public static  T getAopProxy(T invoker) {
        return (T) AopContext.currentProxy();
    }


    /**
     * 获取spring上下文
     */
    public static ApplicationContext context() {
        return getApplicationContext();
    }

}

。。。。

你可能感兴趣的:(java,工具类,excel,java,前端)