Java+Selenium读取Excel数据:控制台无法输出完整内容求助
读取Excel文件时仅第一行显示全列数据的问题排查与解决
我最近尝试用Apache POI读取一个5行20列的Excel文件,但遇到了一个奇怪的问题:控制台里只有第一行能显示所有列的数据,从第二行开始只能显示3-4列。下面是我的相关代码、控制台输出和Excel文件内容截图:
我的读取Excel代码
package testRunner; import java.io.File; import java.io.FileInputStream; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; public class ReadWriteExcel { public static void main(String args[]) throws IOException { try { // 指定要读取的文件路径 File src=new File("D:\\eclipse-workspace\\CucumberWithTestNGForSelenium\\PersonalInformation.xlsx"); // 加载文件 FileInputStream fis=new FileInputStream(src); // 加载工作簿 @SuppressWarnings("resource") XSSFWorkbook wb=new XSSFWorkbook(fis); // 获取第一个工作表 XSSFSheet sh1=wb.getSheetAt(0); // 获取行数 int firstRow=sh1.getFirstRowNum(); int lastRow=sh1.getLastRowNum()+1; int no_of_rows=lastRow-firstRow; for(int i=0;i<no_of_rows;i++) { // 获取当前行的列数 int no_of_columns=sh1.getRow(i).getLastCellNum(); for(int j=0;j<no_of_columns;j++) { System.out.print(" "+ sh1.getRow(i).getCell(j).getStringCellValue()+ " "); } System.out.println(); } } catch(Exception e) { e.getMessage(); } } }
控制台输出
WARNING: An illegal reflective access operation has occurred WARNING: Illegal reflective access by org.apache.poi.openxml4j.util.ZipSecureFile$1 (file:/C:/Users/Mehak/.m2/repository/org/apache/poi/poi-ooxml/3.17/poi-ooxml-3.17.jar) to field java.io.FilterInputStream.in WARNING: Please consider reporting this to the maintainers of org.apache.poi.openxml4j.util.ZipSecureFile$1 WARNING: Use --illegal-access=warn to enable warnings of further illegal reflective access operations WARNING: All illegal access operations will be denied in a future release Title FirstName LastName EmailValidation Password Date Month Year SignUpCheckbox AddessFirstName AddressLastName Company MainAddress AddressLine2 city State PostalCode Country Mobile AddressAlias Mr Simon Duffy aduffy@abc.com
Excel文件内容截图


问题原因分析
- 列数获取逻辑错误:你用
sh1.getRow(i).getLastCellNum()来获取每行的列数,但这个方法返回的是该行最后一个有实际内容/被初始化的单元格的索引+1,如果后面的单元格是空的或者没被Excel初始化(比如只是单元格空白但没被编辑过),它就不会统计这些列,导致后续行的列数被错误计算。 - 未处理空单元格/不存在的单元格:当某行的某个单元格不存在时,
getCell(j)会返回null,直接调用getStringCellValue()会抛出NullPointerException,但你的异常处理只调用了e.getMessage(),没有打印完整的栈轨迹,所以你没看到这个错误,程序只是静默跳过了后续列的输出。 - 未处理不同类型的单元格:如果单元格是数字、日期等类型,直接调用
getStringCellValue()会报错,比如截图里的Date、Month、Year、PostalCode、Mobile这些列可能是数字类型,这也会导致读取失败。
修改后的解决方案代码
package testRunner; import java.io.File; import java.io.FileInputStream; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CellType; import org.apache.poi.xssf.usermodel.XSSFWorkbook; import org.apache.poi.xssf.usermodel.XSSFSheet; public class ReadWriteExcel { public static void main(String args[]) { try { File src=new File("D:\\eclipse-workspace\\CucumberWithTestNGForSelenium\\PersonalInformation.xlsx"); FileInputStream fis=new FileInputStream(src); XSSFWorkbook wb=new XSSFWorkbook(fis); XSSFSheet sh1=wb.getSheetAt(0); // 用第一行的列数作为固定列数(因为表头行是完整的) int totalColumns = sh1.getRow(0).getLastCellNum(); // 获取总行数 int totalRows = sh1.getLastRowNum() + 1; for(int i=0;i<totalRows;i++) { for(int j=0;j<totalColumns;j++) { Cell cell = sh1.getRow(i).getCell(j); String cellValue = getCellValueAsString(cell); System.out.print(" " + cellValue + " "); } System.out.println(); } // 关闭资源 wb.close(); fis.close(); } catch(Exception e) { // 打印完整异常信息,方便排查 e.printStackTrace(); } } // 统一处理不同类型的单元格,转换成字符串 private static String getCellValueAsString(Cell cell) { if(cell == null) { return ""; } switch(cell.getCellType()) { case STRING: return cell.getStringCellValue(); case NUMERIC: // 判断是否是日期类型 if(org.apache.poi.ss.usermodel.DateUtil.isCellDateFormatted(cell)) { return cell.getDateCellValue().toString(); } else { // 数字类型转字符串,避免科学计数法 return String.valueOf((long)cell.getNumericCellValue()); } case BOOLEAN: return String.valueOf(cell.getBooleanCellValue()); case FORMULA: return cell.getCellFormula(); default: return ""; } } }
关键修改点说明
- 用表头行的列数作为固定的总列数,确保遍历所有20列。
- 新增
getCellValueAsString方法,统一处理不同类型的单元格,同时处理空单元格的情况。 - 完善资源关闭和异常处理,打印完整的栈轨迹,方便排查问题。
- 移除了不必要的
@SuppressWarnings("resource"),手动关闭工作簿和输入流,避免资源泄漏。
内容的提问来源于stack exchange,提问作者mehak
相关产品推荐
相关产品推荐

