Java 使用ApachePOI从excel文件读取单元格值

Java 使用ApachePOI从excel文件读取单元格值,java,selenium,apache-poi,Java,Selenium,Apache Poi,我正在使用Selenium 2,并设置了一个LoginTest.java文件,该文件从数据驱动的excel文件中读取数据。我读取用户名和密码,并在登录页面上运行它。它实际上运行良好。数据如下所示: 用户1 pw1 用户2 pw2 用户3 pw3 用户4 pw4 问题是:如果我修改excel文件并将参数的数量更改为以下内容: 用户1 pw1 用户2 pw2 然后运行相同的脚本,ReadExcel类文件返回错误消息: “不支持这种类型的单元” 我认为现在发生的是,第3行和第4行过去在它们的单元格(u

我正在使用Selenium 2,并设置了一个LoginTest.java文件,该文件从数据驱动的excel文件中读取数据。我读取用户名和密码,并在登录页面上运行它。它实际上运行良好。数据如下所示:

用户1 pw1
用户2 pw2
用户3 pw3
用户4 pw4

问题是:如果我修改excel文件并将参数的数量更改为以下内容:

用户1 pw1
用户2 pw2

然后运行相同的脚本,
ReadExcel
类文件返回错误消息:

“不支持这种类型的单元”

我认为现在发生的是,第3行和第4行过去在它们的单元格(user3 pw3和user4 pw4)中包含数据,而现在它们不包含这些数据。因此,以前使用的单元格有一些不同之处,我的
ExcelRead()
类无法忽略。我敢打赌,单元格现在是空的,而以前不是空的,反之亦然。以前保存数据的单元格与从未保存数据的单元格有所不同

(我在互联网上找到了
ExcelRead
,我正在使用它。我不是自己从头开始创建的。除了这个“问题”,它似乎可以很好地读取xcel文件)

谢谢你的帮助

公共类ExcelRead{
公共对象[][]主(字符串[]args)引发异常{
文件excel=新文件(参数[0]);
FileInputStream fis=新的FileInputStream(excel);
HSSF工作手册wb=新的HSSF工作手册(fis);
HSSFSheet ws=wb.getSheet(参数[1]);
int rowNum=ws.getLastRowNum()+1;
int colNum=ws.getRow(0.getLastCellNum();
字符串[][]数据=新字符串[rowNum][colNum];
for(int i=0;i
您下载的代码使用Java Apache POI库读取excel文件。如果查看代码,您将看到
cellToString()
方法不会处理所有类型的单元格类型-它只查找数字和字符串单元格,并抛出您在其他情况下看到的异常

从行中删除单元格值后,单元格值现在为空,您得到的单元格类型为
cell\u type\u blank

您需要扩展
cellToString()
方法中的
switch
语句来处理其他单元格类型,例如
cell.cell\u TYPE\u BLANK
cell.cell\u TYPE\u BOOLEAN

请参阅
单元格
界面上的,以了解不同的单元格类型以及如何处理每种类型

public static String cellToString(HSSFCell cell) {  
    int type;
    Object result;
    type = cell.getCellType();

    switch (type) {

        case Cell.CELL_TYPE_NUMERIC: // numeric value in Excel
        case Cell.CELL_TYPE_FORMULA: // precomputed value based on formula
            result = cell.getNumericCellValue();
            break;
        case Cell.CELL_TYPE_STRING: // String Value in Excel 
            result = cell.getStringCellValue();
            break;
        case Cell.CELL_TYPE_BLANK:
            result = "";
        case Cell.CELL_TYPE_BOOLEAN: //boolean value 
            result: cell.getBooleanCellValue();
            break;
        case Cell.CELL_TYPE_ERROR:
        default:  
            throw new RuntimeException("There is no support for this type of cell");                        
    }

    return result.toString();
}
加上这个

case 3: break;
实际上,您需要检查空单元格类型(
HSSFCell.Cell\u Type\u BLANK

此外,如果发现空单元格,可以使用
i=rowNum
停止
for
循环

有两种以上类型的单元格。
getCellType()
方法可以返回以下整数:

Cell.CELL_TYPE_NUMERIC, Cell.CELL_TYPE_STRING, Cell.CELL_TYPE_FORMULA, Cell.CELL_TYPE_BLANK, Cell.CELL_TYPE_BOOLEAN, Cell.CELL_TYPE_ERROR
编辑:

DEBUG [main] (StreamingWorkbookReader.java:89) - Created temp file 

[C:\Users\UDAY~1\AppData\Local\Temp\tmp-6803178981463652112.xlsx]
Excel Reading - Number Of Sheets: 1, Active Sheet: Sheet1
RowNumber: 1, CellData: User ID, CellNumber: 0
RowNumber: 1, CellData: User Name, CellNumber: 1
RowNumber: 2, CellData: 1, CellNumber: 0
RowNumber: 2, CellData: Steve Jobs, CellNumber: 1
RowNumber: 3, CellData: 2, CellNumber: 0
RowNumber: 3, CellData: Bill Gates, CellNumber: 1
RowNumber: 4, CellData: 3, CellNumber: 0
RowNumber: 4, CellData: Sergey Brin, CellNumber: 1
RowNumber: 5, CellData: 4, CellNumber: 0
RowNumber: 5, CellData: Fritz Sennheiser, CellNumber: 1
RowNumber: 6, CellData: 5, CellNumber: 0
RowNumber: 6, CellData: Thomas Olsen, CellNumber: 1
User ID: 1, User Name: Steve Jobs

根据观察到的Faiz,这将得到一个异常,因为
对象结果
未初始化和未分配。相反,请写入
案例3:返回“”;
当找到空白单元格时,它将返回一个空字符串。无论如何,您的算法不是最有效的。您应该搜索单元格,直到找到空单元格(如果工作表中没有空行),而不是搜索预定义的大区域。您应该能够使用ArrayList而不是Array,从而完全避免在密码检查过程中处理空字符串。

使用JAR下面所需的Java从Excel读取数据。从

若要读取Excel文件,请将其放置在下载或用户所需的位置

Excel文件可能包含不同类型的CellType。在阅读列数据时,您需要提及由Apache POI支持的大部分可用CellType

我参考了以下案例
布尔值、字符串、数值、公式、空白、\u无、错误、
,如果没有案例支持,则转到
getCellValueAsString
方法中的
default

package com.java.file.excel;

import java.io.FileInputStream;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;

import org.apache.poi.ss.usermodel.Cell;
import org.apache.poi.ss.usermodel.Row;
import org.apache.poi.ss.usermodel.Sheet;
import org.apache.poi.ss.usermodel.Workbook;

import com.monitorjbl.xlsx.StreamingReader;

/**
 * 
 * @author udaykiran p
 *
 */
public class ReadExcelFile {

    public static void main(String[] args) {
        try {
            FileInputStream inputStream = new FileInputStream("C:\\Users\\udaykiranp\\Downloads\\Users.xlsx");// Read Excel file from this location
            if (inputStream != null) {
                Workbook wb = StreamingReader.builder().rowCacheSize(100) // number of rows to keep in memory (default to 10)
                        .bufferSize(4096) // buffer size is to use when reading InputStream to file (defaults to 1024)
                        .open(inputStream);
                Sheet sheet = wb.getSheetAt(0);//reading first sheet. You can pass argument as well.
                System.out.println("Excel Reading - Number Of Sheets: "+ wb.getNumberOfSheets() +", Active Sheet: "+ sheet.getSheetName());
                Map<String, String> map = new HashMap<String, String>();
                Iterator<Row> iterator = sheet.iterator();
                int rowCount = 0;
                while(iterator.hasNext()) {
                    Row row = iterator.next();
                    rowCount = row.getRowNum();
                    rowCount++;
                    int columnNum = 0;
                    String key = null, value = null;
                    for(Iterator<Cell> cellIterator = row.cellIterator(); cellIterator.hasNext();) {
                        Cell cell = cellIterator.next();
                        columnNum = cell.getColumnIndex();
                        String cellData = getCellValueAsString(cell);
                        System.out.println("RowNumber: "+ rowCount +", CellData: "+ cellData +", CellNumber: "+ columnNum);
                        //Reading data from Excel upto 6 rows only
//                      if (rowCount == 6) {
                            //rowCount == 1 Headers Section(User ID, User Name)
                            if (rowCount > 1) {
                                if (columnNum == 0) {
                                    key = cellData;//User ID
                                }
                                if (columnNum == 1) {
                                    value = cellData;//User Name
                                }
                            }
//                      }
                    }
                    if (key != null && value != null) {
                        map.put(key, value);
                    }
                }
                String userID = "1";
                System.out.println("User ID: "+ userID +", User Name: "+ map.get("1"));
            }
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

    private static String getCellValueAsString(Cell cell) {
        String cellValue = null;
        switch(cell.getCellType()) {
        case BOOLEAN:
            cellValue = String.valueOf(cell.getBooleanCellValue());
            break;
        case STRING:
            cellValue = String.valueOf(cell.getRichStringCellValue().toString());
            break;
        case NUMERIC:
            Double value = cell.getNumericCellValue();
            if (value != null) {
                String valueAsStr = value.toString();
                int indexOf = valueAsStr.indexOf(".");
                if (indexOf > 0) {
                    cellValue = valueAsStr.substring(0, indexOf);//decimal numbers truncated
                } else {
                    cellValue = value.toString();
                }
            }
            break;
        case FORMULA:
            //if the cell contains formula, this case will be executed.
            cellValue = cell.getStringCellValue();
            break;
        case BLANK:
            cellValue = "";
            break;
        case _NONE:
            cellValue = "";
            break;
        case ERROR:
            throw new RuntimeException("There is no support for this type of cell");
        default:
            cellValue = "";
        }
        return cellValue;
    }
}

是的,我现在明白了,谢谢。我在switch语句中添加了检查空白的语句,但是for循环返回空白,但是,我希望当我删除一行中的数据时,该行根本不会返回。我想我不明白POI类是如何确定行数的。在我的示例中,我删除了第3行d 4但是ExcelRead方法仍然返回4行(2行带数据,2行带空白)。您所拥有的是带有空白单元格的空行。如果您只是想消除这种情况,请通过右键单击行左侧的行标题,然后从关联菜单中单击“删除”来删除这些行。这将只剩下带有数据的行。我明白了,但我想知道删除的单元格数据之间的区别vs一个从未包含数据的单元格?我想知道int rowNum=ws.getLastRowNum()+1;如何知道有多少行数据?如果我删除单元格数据,它仍然认为该行中有数据。如果将excel工作表保存为.csv文件,您将看到它是一个
DEBUG [main] (StreamingWorkbookReader.java:89) - Created temp file 

[C:\Users\UDAY~1\AppData\Local\Temp\tmp-6803178981463652112.xlsx]
Excel Reading - Number Of Sheets: 1, Active Sheet: Sheet1
RowNumber: 1, CellData: User ID, CellNumber: 0
RowNumber: 1, CellData: User Name, CellNumber: 1
RowNumber: 2, CellData: 1, CellNumber: 0
RowNumber: 2, CellData: Steve Jobs, CellNumber: 1
RowNumber: 3, CellData: 2, CellNumber: 0
RowNumber: 3, CellData: Bill Gates, CellNumber: 1
RowNumber: 4, CellData: 3, CellNumber: 0
RowNumber: 4, CellData: Sergey Brin, CellNumber: 1
RowNumber: 5, CellData: 4, CellNumber: 0
RowNumber: 5, CellData: Fritz Sennheiser, CellNumber: 1
RowNumber: 6, CellData: 5, CellNumber: 0
RowNumber: 6, CellData: Thomas Olsen, CellNumber: 1
User ID: 1, User Name: Steve Jobs