今天学习了下使用TestNG、Apache POI和Excel文件进行数据驱动测试,当在写使用POI读取Excel数据时遇到了几个坑,所以在这里记录下!
首先记录下一个获取Excel数据的方法:
有些地方加了一些注释;
package test; import java.io.File; import java.io.FileInputStream; import java.io.FileNotFoundException; import java.io.IOException; import java.util.ArrayList; import java.util.List; import java.util.Locale; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.ss.usermodel.DataFormatter; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class Test001 { public static void main(String[] args) throws IOException { Test001 t =new Test001(); Object[][ ] ee= t.getTestData("D:\\", "qq.xlsx", "文件1"); for(Object a[]:ee) { for(Object c:a) { System.out.print(c+" "); } System.out.println(); } } public Object [][] getTestData (String filePath,String fileName,String sheetName) { File file = new File(filePath + "/"+ fileName); FileInputStream inputStream=null; try { inputStream = new FileInputStream(file); } catch (FileNotFoundException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } DataFormatter formatter = new DataFormatter(Locale.US); Workbook Workbook = null; String fileExtensionName = fileName.substring(fileName.indexOf(".")); try { if(fileExtensionName.equals(".xlsx")){ Workbook = new XSSFWorkbook(inputStream); }else if (fileExtensionName.equals(".xls")){ Workbook = new HSSFWorkbook(inputStream); } } catch (IOException e) { // TODO 自动生成的 catch 块 e.printStackTrace(); } Sheet Sheet = Workbook.getSheet(sheetName); int rowCount = (Sheet.getLastRowNum() - Sheet.getFirstRowNum())+1; List<Object[]> records = new ArrayList <Object[]>(); for (int i=1;i<rowCount;i++){ //因为excel的行列是从0开始的,0行是数据列名称 Row row = Sheet.getRow(i); //用getRow()获取行对象 String fields[] = new String[row.getLastCellNum()]; //用getLastCellNum()动态声明一个数组 for(int j = 0;j<row.getLastCellNum();j++){ //最初写法*************报错 Cannot get a text value from a numeric cell //fields[j]=row.getCell(j).getStringCellValue(); // row.getCell(j).setCellType(row.getCell(j).CELL_TYPE_STRING); // fields[j]=row.getCell(j).getStringCellValue(); //不建议使用这种方法! fields[j] =formatter.formatCellValue(row.getCell(j)); //把elecel每列的元素保存到动态数组 } records.add(fields); //把数组加入到集合中 } //把集合转换成一个二维数组 //这里有一点点不好想的地方,仔细想想fields 数组是在集合中是怎么存储的?????? Object[][] results = new Object[records.size()][]; for (int i=0;i<records.size();i++){ results[i]=records.get(i); } return results; } }
第一坑:
sheetName 是打开的文件显示的什么名字就写什么,不是Sheet1.
如果写错了会显示:
这个错误.
第二坑:
最初在获取每列值的时候是
fields[j]=row.getCell(j).getStringCellValue();
但是会报错:Cannot get a text value from a numeric cell-------无法从数字单元获得字符串值
经过查资料,有一种解决方法是:(不建议用)
String fields[] = new String[row.getLastCellNum()];
for(int j = 0;j<row.getLastCellNum();j++){
row.getCell(j).setCellType(row.getCell(j).CELL_TYPE_STRING);
fields[j]=row.getCell(j).getStringCellValue();
}
records.add(fields);
}
这种方法的确不在报错了,但是eclipse显示不建议使用这种方法,
再次百度(正确方法)
举例:
// Create a formatter, do this once
DataFormatter formatter = new DataFormatter(Locale.US);
.....
for (int i=1; i <= sheet.getLastRowNum(); i++) {
Row r = sheet.getRow(i);
if (r == null) {
// empty row, skip
} else {
String j_username = formatter.formatCellValue(row.getCell(0));
String j_password = formatter.formatCellValue(row.getCell(1));
// Use these
}
}
原因如下(百度翻译过来的,不是很通):
正如在Apache POI javadocs,你不应该使用cell.setcelltype(cell.cell _ _ String类型)得到的数值单元格的字符串值,你会失去所有的格式
相反,作为javadocs解释,你应该使用dataformatter
DataFormatter所做的是以浮点值代表细胞是存储在文件中,随着格式的规则应用到它,并返回一个字符串,你看起来像它的细胞在Excel。
所以,如果你是一个字符串的细胞后,看起来就像你曾期待在Excel中,只是做
格式化程序将返回字符串的细胞,和数字的细胞将格式设置规则的方式对细胞的数目
有什么问题直接参考开头贴出的代码.
最后贴出百度到的参考资料地址:https://stackoverflow.com/questions/30125465/cannot-get-a-text-value-from-a-numeric-cell-poi
还没有评论,来说两句吧...