使用EasyExcel解析导入的excel文件,并处理文件中出现的特殊字符

使用EasyExcel解析导入文件

  1. 自定义Excel工具类,提供导入Excel文件的功能。
  2. 自定义Excel读取监听器Datalistener,用于数据处理。
  3. 实现了ReadListener接口,用于监听Excel的读取过程。
  4. 过滤导入的Excel文件中存在的非中文、英文和数字字符。
 /**
     * 导入文件方法。
     *
     * @param cla               数据模型类,用于解析Excel数据。
     * @param file              待导入的文件,使用MultipartFile封装。
     * @param allowedExtensions 允许的文件扩展名,多个扩展名使用英文逗号分隔。
     * @param maxRows           导入数据的最大行数。
     * @return 解析后的数据列表。
     * @throws IllegalArgumentException         如果允许的文件扩展名为空,抛出此异常。
     * @throws FileFormatIncorrectException     如果上传文件格式不正确,抛出此异常。
     * @throws DataIsEmptyException             如果导入信息为空,抛出此异常。
     * @throws ImportDataLimitExceededException 如果数据超过导入条数限制,抛出此异常。
     * @throws FileReadException                如果文件读取失败,抛出此异常。
     */
    public static <T> List<T> importFile(Class<T> cla, MultipartFile file, String allowedExtensions, int maxRows) {
        // 检查允许的文件扩展名是否为空
        if (allowedExtensions == null || allowedExtensions.isEmpty()) {
            throw new IllegalArgumentException("允许的文件扩展名不能为空");
        }

        // 处理允许的文件扩展名,避免正则表达式错误
        String escapedAllowedExtensions = allowedExtensions.replaceAll("[\\\\^$.|?*+()\\[\\]{}]", "\\\\$0");

        String originalFilename = file.getOriginalFilename();

        // 检查文件类型是否符合要求
        if (!originalFilename.matches(".*\\." + escapedAllowedExtensions + "$")) {
            throw new FileFormatIncorrectException("上传文件格式不正确,请下载模板文件上传");
        }

        try (InputStream inputstream = file.getInputStream()) {
            List<T> list = EasyExcelFactory.read(inputstream, new Datalistener()).sheet(0)
                    .head(cla).headRowNumber(1).doReadSync();
            // 检查导入数据是否为空
            if (list.isEmpty()) {
                throw new DataIsEmptyException("导入信息为空");
            }
            // 检查导入数据是否超过最大行数
            if (list.size() > maxRows) {
                throw new ImportDataLimitExceededException("超过导入条数限制,请确认!");
            }
            return list;
        } catch (IOException e) {
            // 记录文件读取失败的日志
            logError("文件读取失败", e);
            throw new FileReadException("文件读取失败:" + e.getMessage(), e);
        } catch (Exception e) {
            // 记录未预期错误的日志
            logError("导入文件时发生意外错误", e);
            throw new RuntimeException("导入文件时发生意外错误", e);
        }
    }

自定义异常抛出方法—>可以替换为需要的业务异常

 // 错误日志记录方法
    private static void logError(String message, Exception e) {
        // 实现日志记录,这里仅作演示
        System.out.println(message + ": " + e.getMessage());
    }

    // 定义相关异常类
    static class FileFormatIncorrectException extends RuntimeException {
        public FileFormatIncorrectException(String message) {
            super(message);
        }
    }

    static class DataIsEmptyException extends RuntimeException {
        public DataIsEmptyException(String message) {
            super(message);
        }
    }

    static class ImportDataLimitExceededException extends RuntimeException {
        public ImportDataLimitExceededException(String message) {
            super(message);
        }
    }

    static class FileReadException extends RuntimeException {
        public FileReadException(String message, Throwable cause) {
            super(message, cause);
        }
    }

自定义Excel读取监听器

public class Datalistener implements ReadListener<Object> {

    // 定义一个正则表达式,用于过滤字符串中的非中文、英文和数字字符
    public static final String REGEX = "^[\\u4e00-\\u9fa5_a-zA-Z0-9]+$";

    /**
     * 当读取到一行数据时调用此方法。
     * @param object 读取到的数据对象
     * @param analysisContext 分析上下文
     */
    @Override
    public void invoke(Object object, AnalysisContext analysisContext) {
        Class<?> clazz = object.getClass(); // 获取当前对象的类
        Field[] fields = clazz.getDeclaredFields(); // 获取所有声明的字段
        for (Field field : fields) {
            // 判断字段类型是否为String
            if (field.getType().equals(String.class)) {
                ReflectionUtils.makeAccessible(field); // 使私有字段可访问
                try {
                    Object obj = field.get(object); // 获取字段值
                    if (obj != null) {
                        // 如果字段值不为空,则过滤字符串中的非中文、英文和数字字符
                        String value = String.valueOf(obj).replaceAll(REGEX, "");
                        field.set(object, value); // 设置过滤后的值回对象
                    }
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                }

            }
        }
        analysisContext.readRowHolder().setCurrentRowAnalysisResult(object);
    }

    /**
     * 当所有数据读取完成时调用此方法。
     * @param analysisContext 分析上下文
     */
    @Override
    public void doAfterAllAnalysed(AnalysisContext analysisContext) {

    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值