【问题标题】:Apache POI XSSF reading in excel filesApache POI XSSF 读取 excel 文件
【发布时间】:2025-10-22 14:55:02
【问题描述】:

我有一个关于如何使用 Apache 的 XSSF 格式读取 xlsx 文件的快速问题。

现在我的代码如下所示:

InputStream fs = new FileInputStream(filename);   // (1)
XSSFWorkbook wb = new XSSFWorkbook(fs);           // (2)
XSSFSheet sheet = wb.getSheetAt(0);               // (3)

...所有相关的东西都导入了。我的问题是,当我点击运行时,它卡在第 (2) 行,几乎是一个无限循环。 filename 只是一个字符串。

如果有人能给我一些关于如何解决这个问题的示例代码,我将不胜感激。我现在想要的只是从 xlsx 文件中读取单个单元格;我使用 HSSF 处理 xls 文件,没有任何问题。

感谢您的帮助, 安德鲁

【问题讨论】:

  • 同样的代码适用于我。我正在使用 POI 3.7,从 maven 工件 poipoi-ooxml 中提取。我的猜测是您的 .xlsx 文件中有错误。

标签: java apache excel apache-poi xssf


【解决方案1】:

我相信这会回答你的问题:http://poi.apache.org/spreadsheet/quick-guide.html#ReadWriteWorkbook

简而言之,您的代码应如下所示:

InputStream inp = new FileInputStream("workbook.xlsx");
Workbook wb = WorkbookFactory.create(inp);
Sheet sheet = wb.getSheetAt(0);
Row row = sheet.getRow(2);
Cell cell = row.getCell(3);

【讨论】:

    【解决方案2】:
    InputStream inp = null;
            try {
                inp = new FileInputStream("E:/sample_poi.xls");
    
                Workbook wb = WorkbookFactory.create(inp);
                Sheet sheet = wb.getSheetAt(0);
                Header header = sheet.getHeader();
    
                int rowsCount = sheet.getLastRowNum();
                System.out.println("Total Number of Rows: " + (rowsCount + 1));
                for (int i = 0; i <= rowsCount; i++) {
                    Row row = sheet.getRow(i);
                    int colCounts = row.getLastCellNum();
                    System.out.println("Total Number of Cols: " + colCounts);
                    for (int j = 0; j < colCounts; j++) {
                        Cell cell = row.getCell(j);
                        System.out.println("[" + i + "," + j + "]=" + cell.getStringCellValue());
                    }
                }
    
            } catch (Exception ex) {
                java.util.logging.Logger.getLogger(FieldController.class.getName()).log(Level.SEVERE, null, ex);
            } finally {
                try {
                    inp.close();
                } catch (IOException ex) {
                    java.util.logging.Logger.getLogger(FieldController.class.getName()).log(Level.SEVERE, null, ex);
                }
            }
    

    【讨论】:

    • FieldController 从何而来?
    【解决方案3】:

    为什么要将文件分解为 InputStream? XSSFWorkbook 有一个简单地将路径作为字符串的构造函数。只需硬编码字符串的路径。创建工作簿后,您可以从中创建 XSSFSheets。然后是 XSSFCells,它最终将允许您读取单个单元格的内容(单元格基本上基于 x,y 位置)

    【讨论】:

    • 自 poi 3.8 以来已被弃用
    【解决方案4】:

    您可以尝试以下方法。

    private static void readXLSX(String path) throws IOException {
        File myFile = new File(path);
        FileInputStream fis = new FileInputStream(myFile);
    
        // Finds the workbook instance for XLSX file
        XSSFWorkbook myWorkBook = new XSSFWorkbook (fis);
    
        // Return first sheet from the XLSX workbook
        XSSFSheet mySheet = myWorkBook.getSheetAt(0);
    
        // Get iterator to all the rows in current sheet
        Iterator<Row> rowIterator = mySheet.iterator();
    
        // Traversing over each row of XLSX file
        while (rowIterator.hasNext()) {
            Row row = rowIterator.next();
    
            // For each row, iterate through each columns
            Iterator<Cell> cellIterator = row.cellIterator();
            while (cellIterator.hasNext()) {
    
                Cell cell = cellIterator.next();
    
                switch (cell.getCellType()) {
                case Cell.CELL_TYPE_STRING:
                    System.out.print(cell.getStringCellValue() + "\t");
                    break;
                case Cell.CELL_TYPE_NUMERIC:
                    System.out.print(cell.getNumericCellValue() + "\t");
                    break;
                case Cell.CELL_TYPE_BOOLEAN:
                    System.out.print(cell.getBooleanCellValue() + "\t");
                    break;
                default :
    
                }
            }
            System.out.println("");
        }
    }
    

    【讨论】:

      【解决方案5】:

      这很好用:试试吧

      File filename = new File("E:/Test.xlsx");
      FileInputStream isr= new FileInputStream(filename);
      
      Workbook book1 = new XSSFWorkbook(isr);
      Sheet sheet = book1.getSheetAt(0);  
      Iterator<Row> rowItr = sheet.rowIterator();
      

      【讨论】:

      • 我找到了 import org.apache.poi.xssf.usermodel.XSSFWorkbook ,那么 Workbook 对象在哪里?
      【解决方案6】:
      public class ExcelReader{
         public String path;
         public static FileInputStream fis;
      
         public ExcelReader(){
            System.out.println("hello");
         }
      
         public ExcelReader(String path){
            this.path=path;
            fis=new FileInputStream(path);
            XSSFWorkbook workbook=new XSSFWorkbook(fis);
            XSSFSheet sheet=workbook.getSheet("Sheet1");//name of the sheet
            System.out.println(sheet.getSheetName());
            System.out.println(sheet.getLastRowNum());
            System.out.println(sheet.getRow(2).getCell(3));
        }
        public static void main(String[] args) throws IOException {
            ExcelReader excel=new ExcelReader("path of xlsx");
        }
      }
      

      【讨论】:

      • 解释一下这个解决方案的基本原理以及它与之前提供的解决方案有何不同会很有帮助。
      【解决方案7】:

      我有同样的错误,我刚刚用相同的版本更新了 pom 依赖项。它奏效了。

              <!-- https://mvnrepository.com/artifact/org.apache.poi/poi -->
              <dependency>
                  <groupId>org.apache.poi</groupId>
                  <artifactId>poi</artifactId>
                  <version>4.1.0</version>
              </dependency>
              <!-- https://mvnrepository.com/artifact/org.apache.poi/poi-ooxml -->
              <dependency>
                  <groupId>org.apache.poi</groupId>
                  <artifactId>poi-ooxml</artifactId>
                  <version>4.1.0</version>
              </dependency>
      

      【讨论】:

        【解决方案8】:
        // Load sheet- Here we are loading first sheet only
        XSSFSheet xlSheet = wb.getSheetAt(0);
        

        这里的代码只识别第一张工作表 - 在我的 Excel 中存在多个工作表,因此面临将 sheet2 更改为 sheet1(getSheetAt(0)) 的问题...

        【讨论】: