poi导入

一、导入需求

根据下列excel模板,解析数据添加到数据库中
在这里插入图片描述
① 基础信息:根据手机号加密生成openid添加到user表和user_file表
② 量表得分:根据量表名称查id存入结果表;答题串和答题时间串分割拼接

二、准备工作

采用poi导入工具类

package app.test.health.manage.util;

import org.apache.poi.openxml4j.exceptions.InvalidFormatException;
import org.apache.poi.ss.usermodel.*;

import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.lang.reflect.Method;
import java.math.BigDecimal;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

/**
 * Created by xiaofeng.he on 2018/06/22
 * <p>
 *     参考:JML(http://blog.csdn.net/jml1437710575/article/details/52051278)
 * </p>
 * poi 实现 excel 导入 工具类
 */
public class ImportExcelUtil {

    //正则表达式 用于匹配属性的第一个字母
    private static final String REGEX = "[a-zA-Z]";

    /**
     * Excel数据转 list
     * @param originUrl Excel表的所在路径
     * @param datePattern 日期格式 如"yyyy-MM-dd hh:mm:ss"
     * @param filedsIndex 模板定义的属性名的行位置
     * @param startRow 从第几行开始
     * @param endRow 到第几行结束 (0表示所有行;正数表示到第几行结束;负数表示到倒数第几行结束)
     * @param clazz 要返回的对象集合的类型
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> importExcel(String originUrl, String datePattern, int filedsIndex, int startRow, int endRow, Class<T> clazz) throws IOException {
        // 判断文件是否存在
        File file = new File(originUrl);
        if (!file.exists()) {
            throw new IOException("文件名为" + file.getName() + "Excel文件不存在!");
        }
        InputStream fis = new FileInputStream(file);

        return doImportExcel(fis, datePattern, filedsIndex, startRow, endRow, clazz);
    }

    /**
     * Excel数据转 list
     * @param inputStream Excel文件输入流
     * @param datePattern 日期格式 如"yyyy-MM-dd hh:mm:ss"
     * @param filedsIndex 模板定义的属性名的行位置
     * @param startRow 从第几行开始
     * @param endRow 到第几行结束 (0表示所有行;正数表示到第几行结束;负数表示到倒数第几行结束)
     * @param clazz 要返回的对象集合的类型
     * @param <T>
     * @return
     * @throws IOException
     */
    public static <T> List<T> importExcel(InputStream inputStream, String datePattern, int filedsIndex, int startRow, int endRow, Class<T> clazz) throws IOException {
        return doImportExcel(inputStream, datePattern, filedsIndex, startRow, endRow, clazz);
    }

    /**
     * 真正实现
     * @param inputStream
     * @param datePattern
     * @param filedsIndex
     * @param startRow
     * @param endRow
     * @param clazz
     * @param <T>
     * @return
     * @throws IOException
     */
    private static <T> List<T> doImportExcel(InputStream inputStream, String datePattern, int filedsIndex, int startRow, int endRow, Class<T> clazz) throws IOException {
        Workbook wb;
        Sheet sheet;
        Row filedsRow = null;
        List<Row> rowList = new ArrayList<>();
        try {
            // 去读Excel
            // HSSFWorkbook wb = new HSSFWorkbook(fis);
            // 使用workbook 支持2003/2007
            wb = WorkbookFactory.create(inputStream);
            sheet = wb.getSheetAt(0);
            // 获取最后行号
            int lastRowNum = sheet.getLastRowNum();

            int rowLength = lastRowNum;
            if (endRow > 0) {
                rowLength = endRow;
            }
//            else if (endRow < 0) {
//                rowLength = lastRowNum + endRow;
//            }

            // 获取属性列字段
            filedsRow = sheet.getRow(filedsIndex);
            // 循环读取
            Row row;
            for (int i = startRow; i <= rowLength; i++) {
                row = sheet.getRow(i);
                rowList.add(row);
            }

        } catch (IOException e) {
            e.printStackTrace();
            throw e;
        }

        return returnObjectList(datePattern, filedsRow, rowList, clazz);
    }

    /**
     * 功能:返回指定的对象集合
     */
    private static <T>List<T> returnObjectList(String datePattern, Row filedsRow, List<Row> rowList,Class<T> clazz) {
        List<T> objectList=new ArrayList<>();
        try {
            T obj;
            String attribute;
            String value;

            for (Row row : rowList) {
                obj = clazz.newInstance();
                for (int j = 0; j < filedsRow.getLastCellNum(); j++) {
                    attribute = getCellValue(filedsRow.getCell(j));
                    if (!attribute.equals("")) {
                        value = getCellValue(row.getCell(j));
                        setAttrributeValue(obj, attribute, value, datePattern);
                    }
                }
                objectList.add(obj);
            }

        } catch (Exception e) {
            e.printStackTrace();
        }

        return objectList;
    }

    /**
     * 功能:获取单元格的值
     */
    private static String getCellValue(Cell cell) {
        Object result = "";
        if (cell != null) {
            switch (cell.getCellType()) {
                case STRING: //poi的pom文件版本不一致引入的就不一致
                    result = cell.getStringCellValue();
                    break;
                case NUMERIC:
                    result = cell.getNumericCellValue();
                    break;
                case BOOLEAN:
                    result = cell.getBooleanCellValue();
                    break;
                case FORMULA:
                    result = cell.getCellFormula();
                    break;
                case ERROR:
                    result = cell.getErrorCellValue();
                    break;
                case BLANK:
                    break;
                default:
                    break;
            }
        }
        return result.toString();
    }

    /**
     * 功能:给指定对象的指定属性赋值
     */
    private static void setAttrributeValue(Object obj,String attribute,String value, String datePattern) {
        //得到该属性的set方法名
        String method_name = convertToMethodName(attribute,obj.getClass(),true);
        Method[] methods = obj.getClass().getMethods();
        for (Method method : methods) {
            /**
             * 因为这里只是调用bean中属性的set方法,属性名称不能重复
             * 所以set方法也不会重复,所以就直接用方法名称去锁定一个方法
             * (注:在java中,锁定一个方法的条件是方法名及参数)
             */
            if(method.getName().equals(method_name)) {
                Class<?>[] parameterC = method.getParameterTypes();
                try {
                    /**如果是(整型,浮点型,布尔型,字节型,时间类型),
                     * 按照各自的规则把value值转换成各自的类型
                     * 否则一律按类型强制转换(比如:String类型)
                     */
                    if(parameterC[0] == int.class || parameterC[0]== Integer.class) {
                        if(value != null && value.length() > 0) {
                            value = value.substring(0, value.lastIndexOf("."));
                            method.invoke(obj,Integer.valueOf(value));
                        }

                        break;
                    } else if(parameterC[0] == long.class || parameterC[0]== Long.class) {
                        if(value != null && value.length() > 0) {
                            value = value.substring(0, value.lastIndexOf("."));
                            method.invoke(obj,Long.valueOf(value));
                        }
                        break;
                    } else if(parameterC[0] == float.class || parameterC[0]== Float.class) {
                        if(value != null && value.length() > 0) {
                            method.invoke(obj, Float.valueOf(value));
                        }
                        break;
                    } else if(parameterC[0] == double.class || parameterC[0]== Double.class) {
                        if(value != null && value.length() > 0) {
                            method.invoke(obj, Double.valueOf(value));
                        }
                        break;
                    } else if(parameterC[0] == byte.class || parameterC[0]== Byte.class) {
                        if(value != null && value.length() > 0) {
                            method.invoke(obj, Byte.valueOf(value));
                        }
                        break;
                    } else if(parameterC[0] == boolean.class|| parameterC[0]== Boolean.class) {
                        if (value != null && value.length() > 0) {
                            method.invoke(obj, Boolean.valueOf(value));
                        }
                        break;
                    } else if(parameterC[0] == Date.class) {
                        if(value != null && value.length() > 0) {
                            SimpleDateFormat sdf = null;
                            if(value.length()>10){//因为实体中有年月日类型也时分秒类型  所以就多加了一层判断
                                 sdf = new SimpleDateFormat(datePattern);
                            }else{
                                 sdf = new SimpleDateFormat("yyyy-MM-dd");
                            }
                            Date date=null;
                            try {
                                date=sdf.parse(value);
                            } catch (Exception e) {
                                e.printStackTrace();
                            }
                            method.invoke(obj,date);
                        }

                        break;
                    } else if(parameterC[0] == BigDecimal.class) {
                        if (value != null && value.length() > 0) {
                            method.invoke(obj, new BigDecimal(value));
                        }
                        break;
                    } else {
                        if (value != null && value.length() > 0) {
                            method.invoke(obj,parameterC[0].cast(value));
                        }
                        break;
                    }
                } catch (IllegalArgumentException e) {
                    e.printStackTrace();
                } catch (IllegalAccessException e) {
                    e.printStackTrace();
                } catch (InvocationTargetException e) {
                    e.printStackTrace();
                } catch (SecurityException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    /**
     * 功能:根据属性生成对应的set/get方法
     */
    private static String convertToMethodName(String attribute,Class<?> objClass,boolean isSet) {
        /** 通过正则表达式来匹配第一个字符 **/
        Pattern p = Pattern.compile(REGEX);
        Matcher m = p.matcher(attribute);
        StringBuilder sb = new StringBuilder();
        /** 如果是set方法名称 **/
        if(isSet) {
            sb.append("set");
        } else {
            /** get方法名称 **/
            try {
                Field attributeField = objClass.getDeclaredField(attribute);
                /** 如果类型为boolean **/
                if(attributeField.getType() == boolean.class||attributeField.getType() == Boolean.class) {
                    sb.append("is");
                } else {
                    sb.append("get");
                }
            } catch (SecurityException e) {
                e.printStackTrace();
            } catch (NoSuchFieldException e) {
                e.printStackTrace();
            }
        }
        /** 针对以下划线开头的属性 **/
        if(attribute.charAt(0)!='_' && m.find()) {
            sb.append(m.replaceFirst(m.group().toUpperCase()));
        } else {
            sb.append(attribute);
        }
        return sb.toString();
    }

}

实体类
根据导入模板中的列定义实体类的属性名

三、调用和业务代码的处理

    public Map<String,Object> importData(){
        String originUrl="C:\\Users\\1\\Desktop\\导入模板测试2.xlsx";
        int startRow=3;
        int endRow=-1;
        int filedsIndex = 2;
        List<ImportDTO> linesList;
        try {
            linesList = ImportExcelUtil.importExcel(originUrl,"yyyy-MM-dd HH:mm:ss", filedsIndex, startRow, endRow, ImportDTO.class);
//            importDataService.saveProInfo(linesList);
            for (ImportDTO importDTO : linesList) {
                System.out.println(importDTO);
            }
            return ResultUtil.success();
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
            return ResultUtil.error(ResultEnum.SYS_ERROR);
        }
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值