利用POI和反射實現Excel自動識別實體類導入

前言:json

    剛開始導入Excel的時候,每次有新的Excel文件須要導入的時候就須要從新再新寫一個對應的工具來導入excel。因此,鄙人痛定思痛,以爲有必要寫一個能夠萬能導入的Excel工具。app

上代碼:函數

private final static String xls = "xls";
private final static String xlsx = "xlsx";

public static Map<String, Object> readExcelPOIT(Object obj) throws Exception
    {
//        FileInputStream fis = (FileInputStream) file.getInputStream();
        Map<String,Object> jsonObject = new HashMap<>();

        String msg = null;
        List<String> msgList = new ArrayList<>();
        //建立輸入流
        FileInputStream fis = new FileInputStream(new File("g:\\data\\test.xlsx"));
        //經過構造函數傳參
        Workbook workbook = getWorkBookT(new File("g:\\data\\test.xlsx"));
//        Workbook workbook = getWorkBook(file);
        int sheets = workbook.getNumberOfSheets();
        if (sheets<1){
            msg="內容爲空";
            msgList.add(msg);
            jsonObject.put("msg",msgList);
            return jsonObject;
        }
        //獲取工做標名稱
//        for (int i=0;i<sheets;i++){
//            System.out.println(workbook.getSheetName(i));
//
//        }
        //獲取工做表 第一張工做表
        Sheet sheet = workbook.getSheetAt(0);
        //獲取行,行號做爲參數傳遞給getRow方法,第一行從0開始計算
        //獲取第一行
        int firstRowNum = sheet.getFirstRowNum()+2;

        //獲取第一行的第一個值進行判斷是否爲我須要的值
        Row row1 = sheet.getRow(firstRowNum);
        Row row2 = sheet.getRow(firstRowNum-1);

        Class cl = obj.getClass();
        Field[] fs  = cl.getDeclaredFields();
        StringBuilder stringBuilder = new StringBuilder();
        for (Field f : fs ){
            if (stringBuilder.length()==0){
                stringBuilder.append(f.getName());
            }else {
                stringBuilder.append(",");
                stringBuilder.append(f.getName());
            }
        }
        String containsIn = stringBuilder.toString();
        if (row1==null){
            msg="內容爲空";
            msgList.add(msg);
            jsonObject.put("msg",msgList);
            return jsonObject;
        }


//        判斷 所需字段是否存在
        int cellNum = -1;
        short rowNum = row2.getLastCellNum();
        for (int i=0;i<rowNum;i++){
            Cell cell1 = row2.getCell(i);
            cell1.setCellType(CellType.STRING);
            if (cell1!=null){
                String cellValue = cell1.getStringCellValue();

                if (!containsIn.contains(cellValue)){
                    cellNum=i;
                    break;
                }
            }
        }
        if (cellNum!=-1){
            msg="不存在須要的字段";
            msgList.add(msg);
            jsonObject.put("msg",msgList);
            return jsonObject;
        }


        //最後 一列
//        short lastCellNum = row.getLastCellNum();

        //最後一行
        Integer sheetLastRowNum = sheet.getLastRowNum();
        List<Object> list = new ArrayList<>();
        if (sheetLastRowNum<1){
            msg="數據行不存在";
            msgList.add(msg);
        }
        for (int i=firstRowNum+1;i<sheetLastRowNum+1;i++){
            //獲取第i行
            Row row = sheet.getRow(i);
            //獲取該列
            Cell cell1 = null;
            if (row!=null){
                Object object = obj.getClass().newInstance();
                BeanUtils.copyProperties(obj,object);
                for (int j=0;j<rowNum;j++){
                    cell1 = row.getCell(j);
//                    String cellValue = row1.getCell(j).getStringCellValue();
                    String cellValue = row2.getCell(j).getStringCellValue();
                    if (cell1==null){
                        msg="第"+i+"行第"+(j+1)+"列值爲空";
                        msgList.add(msg);
                        break;
                    }
                    if (cell1!=null){
                        cell1.setCellType(CellType.STRING);
                        if (containsIn.contains(cellValue)){
                            String value = cell1.getStringCellValue();
                            Class cal = CustomerPoolAddRequest.class;
                            Field field = cal.getDeclaredField(cellValue);
                            field.setAccessible(true);
                            field.set(object,value);
                        }

                    }
                }
                Object o =AnnotationUtils.validate(object).get("result");
                if (Boolean.TRUE.equals(o)){

                    list.add(object);
                }
            }
        }
        logger.warn("msgList={}",msgList);
        jsonObject.put("list",list);
        jsonObject.put("msg",msgList);
        workbook.close();
        fis.close();
        return jsonObject;
    }


 public static Workbook getWorkBookT(File file) {
        //得到文件名
//        String fileName = file.getOriginalFilename();
        String fileName = file.getName();
        //建立Workbook工做薄對象,表示整個excel
        Workbook workbook = null;
        try {
            //獲取excel文件的io流
//            InputStream is = file.getInputStream();
            FileInputStream is = new FileInputStream(file);
            //根據文件後綴名不一樣(xls和xlsx)得到不一樣的Workbook實現類對象
            if(fileName.endsWith(xls)){
                //2003
                workbook = new HSSFWorkbook(is);
            }else if(fileName.endsWith(xlsx)){
                //2007
                workbook = new XSSFWorkbook(is);
            }
        } catch (IOException e) {
            logger.info(e.getMessage());
        }
        return workbook;
    }
Excel導入規則:
註釋:前三行不被讀取 第二行內容字段與接收實體類字段相同 --
name phone address
姓名 手機號 地址
張三 11011011000 杭州
本次demo中,前三行是被忽略的。第二行的字段與接受的實體類相對應。

如上:只需實體類中用name,phone,address就能接收到姓名爲張三 手機號爲 11011011000 地址爲杭州工具

ps:

這裏咱們只對第一張Excel表進行了處理,須要對全部表進行處理的可自行修改ui

相關文章
相關標籤/搜索