zoukankan      html  css  js  c++  java
  • 基于Java+Selenium的WebUI自动化测试框架(十二)-----读取Excel文件(POI)(2)

      上一篇我们讲了怎么利用Java的反射机制,将Excel的读取到的数据,赋值给我们构造函数中定义的变量。

      接下来就简单了,我们将实际实现这个读取的简单过程。来看下面一段代码。

    private static <T> List<T> transToObject(Class<T> clz,Workbook xssfWorkbook, String sheetName)
                throws InstantiationException, IllegalAccessException,
                InvocationTargetException {
            List<T> list = new ArrayList<T>();
            Sheet xssfSheet = xssfWorkbook.getSheet(sheetName);
            Row firstRow = xssfSheet.getRow(0);
            if(null ==firstRow){
                return list;
            }
            List<Object> heads = getRow(firstRow);
            //添加sheetName字段,用于封装至bean中,与bean中的字段相匹配。
            heads.add("sheetName");
            Map<String, Method> headMethod = getSetMethod(clz, heads);
            for (int rowNum = 1; rowNum <= xssfSheet.getLastRowNum(); rowNum++) {
                try {
                    Row xssfRow = xssfSheet.getRow(rowNum);
                    if (xssfRow == null) {
                        continue;
                    }
                    T t = clz.newInstance();
                    List<Object> data = getRow(xssfRow);
                    //如果发现表数据的列数小于表头的列数,则自动填充为null,最后一位不动,用于添加sheetName数据
                    while(data.size()+1<heads.size()){
                        data.add("");
                    }
                    data.add(sheetName);
                    setValue(t, data, heads, headMethod);
                    list.add(t);
                } catch (IllegalArgumentException e) {
                    // TODO Auto-generated catch block
                    e.printStackTrace();
                }
            }
            return list;
        }

      在这段代码中,我们使用了一个泛型Class<T>来指代我们的构造类,返回的就是一个包含这个构造类的实例集合List<T>。

      另外,xssfWorkbook 是POI中指代一个Excel workbook的变量,sheetName就是我们要读取的sheet名字。

      这里使用了一个小技巧,就是我们的构造函数中,并没有包含sheetName这样一个变量,但是我们实际读取Excel的时候,每个被读取的值都是在一个sheet上的,这样也就必然会有一个sheetName的属性。我们获取第一列的列名之后,可以把“sheetName”这个字段加入List集合中。

      在赋值的时候,我们把参数当中的sheetName赋值给“sheetName”字段,这样,作为一个返回的构造类实例,就包含了变量“sheetName”及具体值sheetName。

      下面,我们再对xssfWorkbook进行再定义,请看下面一段代码:

        public static <T> List<T> readExcel(Class<T> clz, String path,String sheetName) {
            if (null == path || "".equals(path)) {
                return null;
            }
            InputStream is;
            Workbook xssfWorkbook;
            try {
                is = new FileInputStream(path);
           //判断Excel的版本。因为Excel版本不一样,文件的后缀名也不一样
    if (path.endsWith(".xls")) { xssfWorkbook = new HSSFWorkbook(is); } else { xssfWorkbook = new XSSFWorkbook(is); } is.close(); return transToObject(clz, xssfWorkbook, sheetName); } catch (Exception e) { e.printStackTrace(); throw new RuntimeException("转换excel文件失败:" + e.getMessage()); } }

      这样,我们就完成了一个自定义的构造类----“按需读取”Excel的过程。

      在这个过程中,我们需要注意:构造类中的变量名和Excel文件中记录的列名要保持一致,我们才能正常读取数据。

      扩展一下,假如我要读取Excel和N个sheet上的数据,并且也要“按需读取”。怎么办呢。例如:

    Excel有2个Sheet,SheetA和SheetB,这两页上分别写有不同的元素,我想把这些页面元素的内容都读出来,作为一个集合List<T>返回

    SheetA------页面元素A1(网页名,名称,寻找方式,等待时间,路径),SheetA------页面元素A2(网页名,名称,寻找方式,等待时间,路径)

    SheetB------页面元素B1(网页名,名称,寻找方式,等待时间,路径),SheetB------页面元素B2(网页名,名称,寻找方式,等待时间,路径)

      我们来看下面一段代码:

        public static <T> List<T> readExcel(Class<T> clz, String path) {
            System.out.println(path);
            if (null == path || "".equals(path)) {
                return null;
            }
            InputStream is;
            Workbook xssfWorkbook;
            try {
                is = new FileInputStream(path);
                if (path.endsWith(".xls")) {
                    xssfWorkbook = new HSSFWorkbook(is);
                } else {
                    xssfWorkbook = new XSSFWorkbook(is);
                }
                is.close();
                int sheetNumber = xssfWorkbook.getNumberOfSheets();
                List<T> allData = new ArrayList<T>();
                for (int i = 0; i < sheetNumber; i++) {
                    allData.addAll(transToObject(clz, xssfWorkbook,
                            xssfWorkbook.getSheetName(i)));
                }
                return allData;
            } catch (Exception e) {
                e.printStackTrace();
                throw new RuntimeException("转换excel文件失败:" + e.getMessage());
            }
        }

      这里还是比较好处理的,只要直接遍历每个Sheet再存储就好了。

      实际使用例子:

      

        public static void main(String[] args) {
            String excelpath = ".\case-data\same4Test.xls";
            List<positionBean> dataList = new ArrayList<positionBean>();
            dataList = excelUtil.readExcel(positionBean.class,excelpath,"Sheet1");
            for(int i = 0; i < dataList.size();i++) {
                String pageName = dataList.get(i).getPageName();
                String path = dataList.get(i).getPath();
                int waitSec = dataList.get(i).getSec();
                String type = dataList.get(i).getType();
                String positionName = dataList.get(i).getPositionName();
                System.out.println(pageName);
                System.out.println(path);
                System.out.println(waitSec);
                System.out.println(type);
                System.out.println(positionName);
            }
        }

      这样我们就真正完成了使用POI实现“按需读取”

      

  • 相关阅读:
    LostRoutes项目日志——玩家飞机精灵Fighter解析
    quartz Cron表达式一分钟教程
    vue-cli入门
    SQL中merge into用法
    SQLSERVER查询那个表里有数据
    C#实现复杂XML的序列化与反序列化
    MVC和WebApi 使用get和post 传递参数。
    项目管理软件推荐
    JS跨域请求
    Android动画效果translate、scale、alpha、rotate详解
  • 原文地址:https://www.cnblogs.com/generalli2019/p/11439849.html
Copyright © 2011-2022 走看看