通用导入工具类,通过poi和反射实现

将文件从前端上传到后端,就不说了,我的文章里面有上传的,刚开始写,如果有问题欢迎批评指正

首先,先说一下用法,因为之前每增加一个导入模板就要单独开发,比较浪费时间,所以单独搞了个通用类,参数有待解析文件,输出的类,字段数组,开始行数,然后返回一个List

1.我们已经获取到这个文件,先获取文件名的后缀,再根据文件的后缀选择用不同的工作簿来解析

public static Workbook judgmentFileType(File file)  throws IOException {
    Workbook wb = null;
    String fileName = file.getName();
    String extension = fileName.lastIndexOf(".") == -1 ? "" : fileName.substring(fileName.lastIndexOf(".") + 1);
    if ("xls".equals(extension)) { // 读取 office 2003 excel
        wb = new HSSFWorkbook(new FileInputStream(file));
    } else if ("xlsx".equals(extension)) { // 读取Office 2007 excel
        wb = new XSSFWorkbook(new FileInputStream(file));
    } else {
        boolean deleteInfo = file.delete();
        if(!deleteInfo){
            throw new BusinessException(MsgType.ERROR.getFlag(), "文件删除失败");
        }
        throw new BusinessException(MsgType.ERROR.getFlag(), "不支持的文件类型");
    }
    return wb;
}

2.获取到工作簿之后,要获取工作簿里面表格的内容,先获取sheet,再获取物理行数

Workbook wb = judgmentFileType(file);
//获取工作簿的sheet
    sheet = wb.getSheetAt(0);
for (int i = 0; i < sheet.getPhysicalNumberOfRows(); i++) {
        row = sheet.getRow(i);
        if (row == null) {
            continue;
        }
        row = sheet.getRow(i);
        int cells = sheet.getRow(0).getPhysicalNumberOfCells();
for (int j = 0; j < cells; j++) {
    cell = row.getCell(j);
    String cellValue = getCellValue(cell);
    cellValue = cellValue.replaceAll(" ", "");
}

3.然后获取物理行数之后还要再获取每一个单元格的内容

public static String getCellValue(Cell cell) {
    String value = null;
    DecimalFormat df = new DecimalFormat("0");// 格式化 number String // 字符
    DecimalFormat nf = new DecimalFormat("###.######");// 格式化数字
    if(cell != null){
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_STRING:
                value = cell.getStringCellValue();
                break;
            case Cell.CELL_TYPE_NUMERIC:
                if ("@".equals(cell.getCellStyle().getDataFormatString())) {
                    value = df.format(cell.getNumericCellValue());
                } else if ("General".equals(cell.getCellStyle().getDataFormatString())) {
                    value = nf.format(cell.getNumericCellValue());
                } else {
                    value = nf.format(cell.getNumericCellValue());
                }
                break;
            case Cell.CELL_TYPE_BOOLEAN:
                value = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_BLANK:
                value = "";
                break;
            default:
                value = cell.toString();
        }
    }else{
        value = "";
    }
    return value;
}

4.然后利用反射将表格中的数据一行存在一个类中,这个类是动态的,先用反射把传过来的类创建一个出来

Object obj = clazz.newInstance();

然后再获取这个类的方法名

Field[] fields=clazz.getDeclaredFields();

贴上完整代码

public static List analysisExcel(File file, Class clazz, String[] headerFields, int BeginRow) throws IOException{
    Sheet sheet = null;
    Row row = null;
    Cell cell = null;
    List list = new ArrayList();
    Workbook wb = judgmentFileType(file);
    sheet = wb.getSheetAt(0);
    SimpleDateFormat formatter1 = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
    SimpleDateFormat formatter2 = new SimpleDateFormat("yyyy-MM-dd");
    try {
        Map<Integer, String> map = new HashMap<Integer, String>();
        for (int i = BeginRow; i < sheet.getPhysicalNumberOfRows(); i++) {
            row = sheet.getRow(i);
            if (row == null) {
                continue;
            }
            row = sheet.getRow(i);
            int cells = sheet.getRow(0).getPhysicalNumberOfCells();
            Object obj = clazz.newInstance();
            for (int j = 0; j < cells; j++) {
                cell = row.getCell(j);
                String cellValue = getCellValue(cell);
                cellValue = cellValue.replaceAll(" ", "");
                //用反射修改值
                if(PubUtil.isNotEmpty(cellValue)){
                    //获取方法名
                    Field[] fields=clazz.getDeclaredFields();
                    //遍历方法名,从中找出我们所需要的字段
                    for (Field field : fields) {
                        if(headerFields[j].equals(field.getName())){
                            String fieldType = field.getType().getSimpleName();
                            //每个字段对应的类型不一样
                            if ("String".equals(fieldType)) {
                                Method m = obj.getClass().getMethod(getAttributes(headerFields[j]), String.class);
                                m.invoke(obj, cellValue.toString());
                            } else if ("Date".equals(fieldType)) {
                                Date date = null;
                                if(cellValue.length() > 15){
                                    String result = cellValue.substring(0,10)+" "+cellValue.substring(10);
                                    date = formatter1.parse(result);
                                }else{
                                    date = formatter2.parse(cellValue);
                                }
                                Method m = obj.getClass().getMethod(getAttributes(headerFields[j]),Date.class);
                                m.invoke(obj,date);
                            } else if ("BigDecimal".equals(fieldType)) {
                                Method m = obj.getClass().getMethod(getAttributes(headerFields[j]), BigDecimal.class);
                                m.invoke(obj, new BigDecimal(cellValue));
                            }  else {
                                System.out.println("not supper type" + fieldType);
                            }
                        }
                    }
                }
            }
            list.add(obj);
        }
    }  catch (Exception e) {
        e.printStackTrace();
    }
    return list;
}

调用方法

String[] headerFields = {"id","one","two","three","four"};
List list = ImportUtil.analysisExcel(file,BEntity.class, headerFields,1);







评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值