ExcelUtil类实现导入导出

利用反射和泛型,传入要封装的bean和file,转换成对于的list集合

  //用于判断excel版本
    private final static String EXCEL2003L = ".xls";    //2003- 版本的excel
    private final static String EXCEL2007U = ".xlsx";   //2007+ 版本的excel


    /***
     * 通用的Excel导入方法
     *
     * @param file 传入需要导入的file
     * @param tclass 实体Class
     * @param <T> 返回实体信息集合
     * @return
     * @throws IOException
     */
    public static <T> List<T> importBaseExcel(MultipartFile file, Class<T> tclass) throws IOException {

        Workbook workbook = null;

        try {
            //选择合适的文本类型
            workbook = chooseWorkbook(file);

            //获取工作表
            Sheet sheet = workbook.getSheetAt(0);

            //获取sheet中第一行行号
            int firstRowNum = sheet.getFirstRowNum();
            //获取sheet中最后一行行号
            int lastRowNum = sheet.getLastRowNum();

            //获取该实体所有定义的属性 返回Field数组
            Field[] field = tclass.getDeclaredFields();

            List<T> list = new LinkedList();

            /**
             * line = 1 :从表的第二行开始获取记录
             */
            if (null != sheet) {
                //为日期转换限定格式
                //循环插入数据
                for (int i = firstRowNum + 1; i <= lastRowNum; i++) {

                    Row row = sheet.getRow(i);
                    //如果为空,跳过读取下一行
                    if (null == row) {
                        continue;
                    }

                    //根据反射获取Java对象
                    T entity = tclass.newInstance();

                    //除自增编号外,实体字段匹配sheet列
                    for (int j = 0; j < field.length; j++) {
                        //获取属性的名字, 将属性的首字符大写,方便构造set方法
                        String name = "set" + field[j].getName().substring(0, 1).toUpperCase().concat(field[j].getName().substring(1));
                        //获取属性的类型
                        String type = field[j].getGenericType().toString();
                        //getMethod只能调用public声明的方法,而getDeclaredMethod基本可以调用任何类型声明的方法
                        Method method = entity.getClass().getDeclaredMethod(name, field[j].getType());

                        Cell cell = row.getCell(j);

                        //根据属性类型装入值
                        switch (type) {
                            case "char":
                            case "java.lang.Character":
                            case "class java.lang.String":
                                method.invoke(entity, getCellValue(cell));
                                break;
                            case "int":
                            case "class java.lang.Integer":
                                method.invoke(entity, Integer.valueOf(getCellValue(cell)));
                                break;
                            case "class java.util.Date":
                                method.invoke(entity, cell.getDateCellValue());
                                break;
                            case "double":
                            case "class java.lang.Double":
                                method.invoke(entity, Double.valueOf(getCellValue(cell)));
                                break;
                            case "float":
                            case "class java.lang.Float":
                                method.invoke(entity, Float.valueOf(getCellValue(cell)));
                                break;
                            case "long":
                            case "class java.lang.Long":
                                method.invoke(entity, Long.valueOf(getCellValue(cell)));
                                break;
                            case "short":
                            case "class java.lang.Short":
                                method.invoke(entity, Short.valueOf(getCellValue(cell)));
                                break;
                            case "class java.math.BigDecimal":
                                method.invoke(entity, new BigDecimal(Double.valueOf(getCellValue(cell))));
                                break;
                            default:
                                break;
                        }
                    }
                    //添加到list集合中
                    list.add(entity);
                }
                return list;
            } else {
                //没有内容
                return null;
            }
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            workbook.close();
        }
        return null;
    }

    /**
     * 通用的Excel导出方法
     *
     * @param excelName           Excel表名
     * @param titles              Excel的表头内容
     * @param infoList            Excel的表体内容
     * @param httpServletResponse 用于响应客户端的response
     * @throws IllegalAccessException
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     */
    public static void exportBaseExcel(String excelName, String[] titles, List infoList, HttpServletResponse httpServletResponse) throws IllegalAccessException, NoSuchMethodException, InvocationTargetException {
        //首先,将list集合转换为数组
        List<Object[]> values = beanToArraysUtil(infoList);

        // 第一步,创建一个webbook,对应一个Excel文件
        HSSFWorkbook wb = new HSSFWorkbook();
        // 第二步,在webbook中添加一个sheet,对应Excel文件中的sheet
        HSSFSheet sheet = wb.createSheet("会议签到表");
        // 第三步,在sheet中添加表头第0行,注意老版本poi对Excel的行数列数有限制short
        HSSFRow row = sheet.createRow((int) 0);
        // 第四步,创建单元格,并设置值表头 设置表头居中
        HSSFCellStyle style = wb.createCellStyle();
        style.setAlignment(HSSFCellStyle.ALIGN_CENTER); // 创建一个居中格式


        //第五步,创建标题
        for (int i = 0; i < titles.length; i++) {
            HSSFCell cell = row.createCell((short) i);
            cell.setCellValue(titles[i]);
        }


        //第六步,写入实体数据,遍历创建内容
        for (int i = 0; i < values.size(); i++) {//总共多少行
            Object[] str = values.get(i);
            row = sheet.createRow(i + 1);//第几行
            for (int j = 0; j < str.length; j++) {
                //将内容按顺序赋给对应的列对象
                row.createCell(j).setCellValue(str[j].toString());//每行塞什么数据
            }
        }

        //第六步,下载excel表格
        OutputStream out = null;
        try {
            out = httpServletResponse.getOutputStream();
            String fileName = excelName + ".xls";// 文件名
            httpServletResponse.setContentType("application/x-msdownload");//文件格式
            httpServletResponse.setHeader("Content-Disposition", "attachment; filename="
                    + URLEncoder.encode(fileName, "UTF-8"));//响应头以及文件名,编码格式
            wb.write(out);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                out.close();
            } catch (IOException e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 功能分析:根据文件选择excel版本
     *
     * @return
     * @throws Exception
     */
    private static Workbook chooseWorkbook(MultipartFile file) throws Exception {

        Workbook workbook = null;

        InputStream ins = file.getInputStream();

        String filename = file.getOriginalFilename();
        String fileType = (filename.substring(filename.lastIndexOf("."), filename.length())).toLowerCase();

        if (EXCEL2003L.equals(fileType)) {
            workbook = new HSSFWorkbook(ins);  //2003-
        } else if (EXCEL2007U.equals(fileType)) {
            workbook = new XSSFWorkbook(ins);  //2007+
        } else {
            throw new Exception("解析的文件格式有误!");
        }

        return workbook;
    }

    /***
     * 功能分析:根据类型获取对应的值
     *
     * @param cell 对应的表单元
     * @return
     */
    public static String getCellValue(Cell cell) {
        String cellValue = "";
        if (cell == null) {
            return cellValue;
        }
        // 判断数据的类型
        switch (cell.getCellType()) {
            case Cell.CELL_TYPE_NUMERIC: // 数字
                //short s = cell.getCellStyle().getDataFormat();
                if (HSSFDateUtil.isCellDateFormatted(cell)) {// 处理日期格式、时间格式
                    SimpleDateFormat sdf = null;
                    // 验证short值
                    if (cell.getCellStyle().getDataFormat() == 14) {
                        sdf = new SimpleDateFormat("yyyy/MM/dd");
                    } else if (cell.getCellStyle().getDataFormat() == 21) {
                        sdf = new SimpleDateFormat("HH:mm:ss");
                    } else if (cell.getCellStyle().getDataFormat() == 22) {
                        sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm:ss");
                    } else {
//                        throw new RuntimeException("日期格式错误!!!");
                        sdf = new SimpleDateFormat("yyyy-MM-dd:HH:mm:ss");
                    }
                    Date date = cell.getDateCellValue();
                    cellValue = sdf.format(date);
                } else if (cell.getCellStyle().getDataFormat() == 0) {//处理数值格式
                    cell.setCellType(Cell.CELL_TYPE_STRING);
                    cellValue = String.valueOf(cell.getRichStringCellValue().getString());
                }
                break;
            case Cell.CELL_TYPE_STRING: // 字符串
                cellValue = String.valueOf(cell.getStringCellValue());
                break;
            case Cell.CELL_TYPE_BOOLEAN: // Boolean
                cellValue = String.valueOf(cell.getBooleanCellValue());
                break;
            case Cell.CELL_TYPE_FORMULA: // 公式
                cellValue = String.valueOf(cell.getCellFormula());
                break;
            case Cell.CELL_TYPE_BLANK: // 空值
                cellValue = null;
                break;
            case Cell.CELL_TYPE_ERROR: // 故障
                cellValue = "非法字符";
                break;
            default:
                cellValue = "未知类型";
                break;
        }
        return cellValue;
    }

    /**
     * 功能分析:把对象集合转换成数组集合
     *
     * @param list:需要操作的实体类集合
     * @return
     * @throws NoSuchMethodException
     * @throws InvocationTargetException
     * @throws IllegalAccessException
     */
    private static List<Object[]> beanToArraysUtil(List list) throws NoSuchMethodException, InvocationTargetException, IllegalAccessException {
        //设置用到的变量参数
        String name = null, type = null, m_name = null;
        Object value = null;
        //创建一个二维字符串数组存放数据
        List<Object[]> list1 = new ArrayList<>();
        //获取实体类方法操作对象
        Method m = null;
        //判断要提取实体类属性数据的集合是否为空
        if (list != null) {
            //遍历集合中的实体类
            for (int y = 0; y < list.size(); y++) {
                //获取每一个实体类
                Object object = list.get(y);
                //获取实体类的所有属性,返回Field数组
                Field[] fields = object.getClass().getDeclaredFields();
                //创建一个数组存放实体类属性数据
                Object[] str = new Object[fields.length];
                //遍历实体类的所有属性
                for (int i = 0; i < fields.length; i++) {
                    name = fields[i].getName();//获取属性的名字
                    m_name = name.substring(0, 1).toUpperCase() + name.substring(1); //将属性的首字符大写,方便构造get,set方法
                    type = fields[i].getGenericType().toString();    //获取属性的类型
                    //判断属性的类型修改数据结构
                    switch (type) {
                        case "class java.lang.String":
                            m = object.getClass().getMethod("get" + m_name);  //组装getter方法
                            value = (String) m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                                /**
                                 * 你可以进行附加操作
                                 */
                            }
                            break;
                        case "class java.lang.Double":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                            }
                            break;
                        case "class java.lang.Boolean":
                            m = object.getClass().getMethod("get" + m_name);  //组装getter方法
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                            }
                            break;
                        case "class java.lang.Integer":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object); //调用getter方法获取属性值
                            if (value != null) {

                            }
                            break;
                        case "class java.util.Date":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                                value = new SimpleDateFormat("yyyy-MM-dd").format(value);//改变时间的格式
                            }
                            break;
                        case "class java.lang.Float":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                            }
                            break;
                        case "class java.lang.Long":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {
                            }
                            break;
                        case "class java.lang.Byte":
                            m = object.getClass().getMethod("get" + m_name);
                            value = m.invoke(object);    //调用getter方法获取属性值
                            if (value != null) {

                            }
                            break;
                    }
                    //把实体类中的属性存放到一个字符串数组中
                    str[i] = value;
                }
                //把字符串数组存放到集合中

                list1.add(str);
            }
        }

        return list1;
    }

 

多谢下面这位大佬的帮助

参考: https://blog.csdn.net/qq_40162735/article/details/84874862

           https://blog.csdn.net/qq_40162735/article/details/84954687

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 1
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值