Java根据指定Excel位置读取数据到类中

一、需要使用到的注解

  1. 此注解标注在类上,主要是读取那个sheet页面,如果不使用默认读取第一页

    @Target({ElementType.TYPE})
    @Retention(RetentionPolicy.RUNTIME)
    @Inherited
    public @interface PesExcelEntity {
        int sheetIndex() default 0;
    }
    
  2. 此注解用于标注在属性上,怎么读取,读取那个单元格

    
    @Retention(RetentionPolicy.RUNTIME)
    @Target(ElementType.FIELD)
    public @interface PesExcel {
    
        //    列
        int columnIndex() default 0;
    
        //    行
        int rowIndex() default 0;
    
        //    跳过指定字符
        int offset() default 0;
    
        //    数据类型 string int等等。。。。。。
        String dataType() default "";
    
        //    字段名称
        String fieldName() default "";
    
        //    错误提示
        String errMsg() default "";
    
        //    执行的方法
        String invokeMethodName() default "";
    
        Class<?>[] parameterTypes() default {};
    }
    
    
  3. 类型类

    /**
     * excel 数据类型
     *
     * @author l
     */
    public class ExcelDataType {
        public static final String INT = "int";
        public static final String METHOD = "method";
    }
    
    
  4. 使用方式

    @PesExcel(columnIndex = 7, rowIndex = 3, dataType = ExcelDataType.METHOD, invokeMethodName = "cn.ac.nercis.pes.core.utils.ExcelCheckUtil#isContainChinese", parameterTypes = {String.class}, fieldName = "项目编号", errMsg = "不能包含中文")

二、工具类如下

代码

/**
 * excel工具类
 *
 * @author lcs
 * @date 2022-5-17
 */
@Slf4j
public class ExcelUtil {

    /**
     * @param inputstream 文件流
     * @param objeType    转换的对象
     * @param <T>         返回的对象
     * @return
     */
    public static <T> T importExcel(InputStream inputstream, Class<T> objeType) {
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        ArrayList<String> errList = new ArrayList<>(objeType.getDeclaredFields().length * 2);
        try {
            Workbook workbook = getWorkbook(inputstream, baos);

            Object bean = Class.forName(objeType.getName()).getDeclaredConstructor().newInstance();

//            获取要读取的sheet
            int sheetIndex = 0;
            PesExcelEntity objeTypeAnnotation = objeType.getAnnotation(PesExcelEntity.class);
            if (objeTypeAnnotation != null) {
                sheetIndex = objeTypeAnnotation.sheetIndex();
            }
            Sheet sheetAt = workbook.getSheetAt(sheetIndex);
            if (sheetAt == null) {
                throw new RuntimeException("您读取的sheet 不存在!!");
            }
            for (Field declaredField : objeType.getDeclaredFields()) {
                PesExcel annotation = declaredField.getAnnotation(PesExcel.class);
                NotBlank notBlank = declaredField.getAnnotation(NotBlank.class);

                if (null != annotation) {
                    Cell cell = sheetAt.getRow(annotation.rowIndex()).getCell(annotation.columnIndex());
                    if (cell != null) {
                        String cellValue = PoiCellUtil.getCellValue(cell);
//                      数据类型校验
                        dataTypeCheck(annotation, cellValue);

//                        跳过字符
                        int offset = annotation.offset();

                        if (offset > cellValue.length()) {
                            offset = cellValue.length();
                        }
                        cellValue = cellValue.substring(offset);

                        if (notBlank != null) {
//                            有非空校验
                            if (StringUtils.isBlank(cellValue)) {
                                errList.add(notBlank.message());
                            }
                        }
                        Field field = bean.getClass().getDeclaredField(declaredField.getName());
                        if (!field.canAccess(bean)) {
                            field.setAccessible(true);
                        }
                        field.set(bean, cellValue);
                    }
                }
            }
//            异常校验,如果数据存在异常则抛出
            errCheck(errList);
            return (T) bean;
        } catch (Exception e) {
            log.error("解析execl异常: {}", e.getMessage());
            throw new RuntimeException(e.getMessage());
        } finally {
            IOUtils.closeQuietly(baos);
        }
    }

    private static void dataTypeCheck(PesExcel annotation, String cellValue) {
        //                        校验数据类型
        if (cn.ac.nercis.pes.core.utils.StringUtils.isNotBlank(annotation.dataType())) {

            log.info("读取的字段信息: {}", cellValue);

            log.info("数据字段: {}", annotation.fieldName());

            try {
                switch (annotation.dataType()) {
                    case ExcelDataType.INT:
                        boolean number = NumberUtil.isNumber(cellValue);
                        if (!number) {
                            throw new RuntimeException();
                        }
                        break;
                    case ExcelDataType.METHOD:
                        String invokeMethodName = annotation.invokeMethodName();
                        if (StringUtils.isBlank(invokeMethodName)) {
                            throw new ExcelCheckUtil.ExcelCheckErr("调用方法不存在");
                        }
//                        执行方法
                        String[] classAndMethod = invokeMethodName.split("#");
                        if (classAndMethod.length != 2) {
                            throw new ExcelCheckUtil.ExcelCheckErr("调用参数异常,请检查");
                        }
                        Class<?> aClass = Class.forName(classAndMethod[0]);
                        Method method = aClass.getMethod(classAndMethod[1], annotation.parameterTypes());
                        try {
                            method.invoke(aClass, cellValue);
                        } catch (InvocationTargetException e) {
                            throw new ExcelCheckUtil.ExcelCheckErr(e.getTargetException().getMessage());
                        }
                        break;
                }
            } catch (ClassNotFoundException e) {
                log.error("错误信息: {},{}", e.getMessage(), e.toString());
                throw new RuntimeException("未找到相关实体");
            } catch (NoSuchMethodException e) {
                log.error("错误信息: {},{}", e.getMessage(), e.toString());
                throw new RuntimeException("未找到相关可执行的方法");
            } catch (ExcelCheckUtil.ExcelCheckErr e) {
                log.error("错误信息:{},{}", e.getMessage(), e.toString());
                throw new RuntimeException(annotation.fieldName() + e.getMessage());
            } catch (Exception e) {
                log.error("必要字段数据类型异常: {}《《《《《《《《《《《《{}", e.getMessage(), e.toString());
                throw new RuntimeException(annotation.fieldName() + (cn.ac.nercis.pes.core.utils.StringUtils.isNotBlank(annotation.errMsg()) ? annotation.errMsg() : "数据格式异常"));
            }
        }
    }

    public static void errCheck(List<String> errList) {
        if (CollUtil.isNotEmpty(errList)) {
            throw new RuntimeException(String.join(";", errList));
        }
    }

    public static Workbook getWorkbook(InputStream inputstream, ByteArrayOutputStream baos) throws IOException {
        byte[] buffer = new byte[1024];
        int len;
        while ((len = inputstream.read(buffer)) > -1) {
            baos.write(buffer, 0, len);
        }
        baos.flush();

        InputStream userIs = new ByteArrayInputStream(baos.toByteArray());
        try {
            return WorkbookFactory.create(userIs);
        } catch (Exception e) {
            log.error("异常信息:  {},{}", e.getMessage(), e.toString());
            throw new RuntimeException("请检查您的文件格式是否正确!!");
        } finally {
            IOUtils.closeQuietly(baos);
        }

    }


    /**
     * 获取合并单元格的值
     *
     * @param sheet
     * @param row
     * @param column
     * @return
     */
    public static String getMergedRegionValue(Sheet sheet, int row, int column) {
        if (!isMergedRegion(sheet, row, column)) {
            return PoiCellUtil.getCellValue(sheet.getRow(row).getCell(column));
        }


        int sheetMergeCount = sheet.getNumMergedRegions();

        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress ca = sheet.getMergedRegion(i);
            int firstColumn = ca.getFirstColumn();
            int lastColumn = ca.getLastColumn();
            int firstRow = ca.getFirstRow();
            int lastRow = ca.getLastRow();

            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    Row fRow = sheet.getRow(firstRow);
                    Cell fCell = fRow.getCell(firstColumn);
                    return PoiCellUtil.getCellValue(fCell);
                }
            }
        }

        return null;
    }

    /**
     * 判断指定的单元格是否是合并单元格
     *
     * @param sheet
     * @param row    行下标
     * @param column 列下标
     * @return
     */
    public static boolean isMergedRegion(Sheet sheet, int row, int column) {
        int sheetMergeCount = sheet.getNumMergedRegions();
        for (int i = 0; i < sheetMergeCount; i++) {
            CellRangeAddress range = sheet.getMergedRegion(i);
            int firstColumn = range.getFirstColumn();
            int lastColumn = range.getLastColumn();
            int firstRow = range.getFirstRow();
            int lastRow = range.getLastRow();
            if (row >= firstRow && row <= lastRow) {
                if (column >= firstColumn && column <= lastColumn) {
                    return true;
                }
            }
        }
        return false;
    }
}

使用方式

在这里插入图片描述

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
Java,可以使用Apache POI库来读取和写入Excel文件。下面是一个简单的步骤来读取Excel文件、设置数据并导出: 1. 首先,添加Apache POI库的依赖项到你的项目。可以在Maven项目的pom.xml文件添加如下依赖项: ```xml <dependency> <groupId>org.apache.poi</groupId> <artifactId>poi</artifactId> <version>4.1.2</version> </dependency> ``` 2. 读取Excel文件。使用`WorkbookFactory`类的`create(InputStream)`方法打开Excel文件并创建`Workbook`对象。例如: ```java InputStream inputStream = new FileInputStream("path/to/excel.xlsx"); Workbook workbook = WorkbookFactory.create(inputStream); ``` 3. 获取特定的工作表。通过调用`Workbook`对象的`getSheetAt(int index)`方法,可以获取指定索引的工作表。例如: ```java Sheet sheet = workbook.getSheetAt(0); // 获取第一个工作表 ``` 4. 遍历工作表的行和列。通过调用`Sheet`对象的`getRow(int index)`和`getCell(int index)`方法,可以获取指定索引的行和列。例如: ```java for (Row row : sheet) { for (Cell cell : row) { // 获取单元格的值 String value = cell.getStringCellValue(); // 设置单元格的值 cell.setCellValue("New Value"); } } ``` 5. 导出Excel文件。最后,可以使用`Workbook`对象的`write(OutputStream)`方法将修改后的Excel文件导出。例如: ```java OutputStream outputStream = new FileOutputStream("path/to/new_excel.xlsx"); workbook.write(outputStream); ``` 以上就是读取Excel文件、设置数据并导出的简单示例。希望对你有所帮助!

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值