上一篇我们讲了怎么利用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实现“按需读取”

  

基于Java+Selenium的WebUI自动化测试框架(十二)-----读取Excel文件(POI)(2)的更多相关文章

  1. 基于Java+Selenium的WebUI自动化测试框架(二)-----页面操作接口

    在有了基础的Position类之后,我们需要考虑我们在寻找完页面元素之后,需要做什么.这个“做”什么,可以理解为我们在页面上需要对应的一系列动作.比如:点击,输入,切换窗口,寻找元素,判断元素是否存在 ...

  2. 基于Java+Selenium的WebUI自动化测试框架(十四)-----使用TestNG的Sample

    到目前为止,我们所写的东西,都是集中在如何使用Selenium和Java来定位和读取元素.那么,到底如何具体开展测试,如何实现参数化,如何实现判定呢?下面,我们来看看Java应用程序的测试框架吧. 当 ...

  3. 基于Java+Selenium的WebUI自动化测试框架(十)-----读取Excel文件(JXL)

    之前,我们使用了读取XML文件的方式来实现页面元素的读取,并做成了基础页面类.下面,我们来进行一些扩展,通过Excel来读取页面元素. Excel的使用,大多数人应该都不陌生.那么Java读取Exce ...

  4. 基于Java+Selenium的WebUI自动化测试框架(一)---页面元素定位器

    对于自动化测试,尤其是UI的自动化测试.是很多做黑盒功能测试的同学,入门自动化测试一个最为直观的或者说最容易理解的途径之一. 对于手工测试和自动化测试的优劣,网上有很多论述,在这里不作展开讨论.但是, ...

  5. 基于Java+Selenium的WebUI自动化测试框架(八)-----读取元素(XML文件)

    我们继续回到自动化测试框架的主线上来,在前面的文章中,我们定义一个页面元素的主要参数有:路径,找寻方式,等待时间,名称,这个四个参数.另外,我们还需要考虑一个问题,就是网站的页面. 举个例子来说,如果 ...

  6. 基于Java+Selenium的WebUI自动化测试框架(六)---浏览器初始化

    本篇我们来讨论,如何写一个浏览器初始化的类.在写之前,先思考一下,我们需要一个什么样的初始化? 先来看看使用原生的Java + selenium是怎么做的.(以firefox为例) System.se ...

  7. 基于Java+Selenium的WebUI自动化测试框架(九)-----基础页面类(BasePage)

    上篇我们写了java读取xml文件的类,实现了可以从xml文件读取元素的方式.那么,接下来我们需要考虑一个问题.我们拿了这些元素之后怎么去操作呢? 先来看看我们手工测试的时候是怎么进行的. 双击浏览器 ...

  8. 基于Java+Selenium的WebUI自动化测试框架(十一)-----读取Excel文件(POI)(1)

    上一篇说了利用JXL的jar包来读取Excel的代码.在Java中,还可以用另外一种jar包来读取Excel的内容,那就是Apache的POI. 这里和之前一样,需要导入POI的jar包,建议导入这三 ...

  9. 基于Java+Selenium的WebUI自动化测试框架(十三)-----基础页面类BasePage(Excel)

    前面,我们讲了如何使用POI进行Excel的“按需读取”.根据前面我们写的BasePageX,我们可以很轻松的写出来基于这个“按需读取”的BasePage. package webui.xUtils; ...

随机推荐

  1. 【c++基础】C与C++接口相互调用

    前言 编译程序的时候出现错误,入口程序如果是cpp文件可以编译成功,如果是c程序则出错.一般这个问题是c与c++之间接口相互调用出现的问题. 出现的错误是undefined reference to ...

  2. kexue shangwang

    根据实践,pptp.IPsec甚至OpenVPN等kexue上网法已经无法顺利翻越GFW.通过抓包可知,GFW会将pptp的握手期间的ack包吞掉,导致本地一直无法收到服务器端的响应.而OpenVPN ...

  3. 【Python学习之七】类和对象

    环境 虚拟机:VMware 10 Linux版本:CentOS-6.5-x86_64 客户端:Xshell4 FTP:Xftp4 python3.6 一.面向对象编程1.概念(1)面向对象编程(OOP ...

  4. string 与 int double 的转化

    #include <iostream> #include <string> #include <sstream> using namespace std; int ...

  5. Windows平台为 ElasticSearch 6.x 安装 Head 客户端插件

    背景知识 ES 5.x 以上版本安装 head 需要 node 和 grunt 环境(之前的直接用plugin命令即可安装). 操作步骤 1. 安装 ElasticSearch 6.x,访问 http ...

  6. Prometheus入门到放弃(5)之AlertManager部署

    alertmanager与exporters.cadvisor一样,都是独立于prometheus项目,这里我们也使用docker方式部署alertmanager. 1.下载镜像 镜像地址:https ...

  7. CSP前的板子们

    见窝的luogu博客qwq noip前的板子们

  8. Python-12-装饰器

    一.定义 器即函数 装饰即修饰,意指为其他函数添加新功能 装饰器定义:本质就是函数,功能是为其他函数添加新功能 原则: 1.不修改被装饰函数的源代码(开放封闭原则) 2.为被装饰函数添加新功能后,不修 ...

  9. shiro源码解析

    一.web.xml 文件中配置的 DelegatingFilterProxy 的 <filter-name>为啥与Spring文件中配置的ShiroFilterFactoryBean的Be ...

  10. Gym102028G Shortest Paths on Random Forests 生成函数、多项式Exp

    传送门 神仙题-- 考虑计算三个部分:1.\(n\)个点的森林的数量,这个是期望的分母:2.\(n\)个点的所有森林中存在最短路的点对的最短路径长度之和:3.\(n\)个点的所有路径中存在最短路的点对 ...