Java 无法使用Apache POI读取Excel 2010文件。第一行号是-1

Java 无法使用Apache POI读取Excel 2010文件。第一行号是-1,java,excel,apache-poi,excel-2010,xssf,Java,Excel,Apache Poi,Excel 2010,Xssf,我正在使用ApachePOIAPI当前版本3-10-FINAL尝试这一点。下面的测试代码 import java.io.FileInputStream; import org.apache.poi.xssf.usermodel.XSSFSheet; import org.apache.poi.xssf.usermodel.XSSFWorkbook; public class ExcelTest { public static void main(String[] args) thro

我正在使用ApachePOIAPI当前版本3-10-FINAL尝试这一点。下面的测试代码

import java.io.FileInputStream;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;

public class ExcelTest {

    public static void main(String[] args) throws Exception {
        String filename = "testfile.xlsx";
        XSSFWorkbook wb = new XSSFWorkbook(new FileInputStream(filename));
        XSSFSheet sheet = wb.getSheetAt(0);
        System.out.println(sheet.getFirstRowNum());
    }
}
结果第一行号为-1,现有行返回为null。该测试文件是由Excel 2010创建的,我无法控制该部件,可以使用Excel读取,不会出现警告或问题。如果我用我的Excel 2013版本打开并保存该文件,它可以按预期完全读取


如果有任何关于我为什么不能阅读原始文件或如何阅读原始文件的提示,我们将不胜感激。

testfile.xlsx是使用SpreadsheetGear 7.1.1.120创建的。用一个可以处理ZIP存档的软件打开XLSX文件,并查看/xl/workbook.xml以了解这一点。在工作表/工作表?.xml文件中,请注意所有行元素都没有行号。如果我在第一行标记中放入一个行号,如ApachePOI可以读取这一行

如果说到这个问题,谁应该为此负责,那么答案肯定是ApachePOI和SpreadsheetGear;-。Apache POI,因为row元素中的属性r是可选的。但是SpreadsheetGear也是因为如果Excel本身使用r属性,那么没有理由不使用它

如果无法以Apache POI可以直接读取的格式获取testfile.xlsx,则必须使用底层对象。以下内容适用于testfile.xlsx:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;

import java.util.List;

class Testfile {

 public static void main(String[] args) {
  try {

   InputStream inp = new FileInputStream("testfile.xlsx");
   Workbook wb = WorkbookFactory.create(inp);

   Sheet sheet = wb.getSheetAt(0);

   System.out.println(sheet.getFirstRowNum());

   CTWorksheet ctWorksheet = ((XSSFSheet)sheet).getCTWorksheet();

   CTSheetData ctSheetData = ctWorksheet.getSheetData();

   List<CTRow> ctRowList = ctSheetData.getRowList();

   Row row = null;
   Cell[] cell = new Cell[2];

   for (CTRow ctRow : ctRowList) {
    row = new MyRow(ctRow, (XSSFSheet)sheet);
    cell[0] = row.getCell(0);
    cell[1] = row.getCell(1);
    if (cell[0] != null && cell[1] != null && cell[0].toString() != "" && cell[1].toString() != "") 
       System.out.println(cell[0].toString()+"\t"+cell[1].toString());
   }

  } catch (InvalidFormatException ifex) {
  } catch (FileNotFoundException fnfex) {
  } catch (IOException ioex) {
  }
 }
}

class MyRow extends XSSFRow {
 MyRow(org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow row, XSSFSheet sheet) {
  super(row, sheet);
 }
}
我使用了:

org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow 它们是Apache POI二进制发行版POI-bin-3.10.1-20140818的一部分,在POI-ooxml-schemas-3.10.1-20140818.jar中有

有关文档,请参阅


我已经扩展了XSSFRow,因为我们不能直接使用XSSFRow构造函数,因为它具有受保护的访问权限

testfile.xlsx是使用SpreadsheetGear 7.1.1.120创建的。用一个可以处理ZIP存档的软件打开XLSX文件,并查看/xl/workbook.xml以了解这一点。在工作表/工作表?.xml文件中,请注意所有行元素都没有行号。如果我在第一行标记中放入一个行号,如ApachePOI可以读取这一行

如果说到这个问题,谁应该为此负责,那么答案肯定是ApachePOI和SpreadsheetGear;-。Apache POI,因为row元素中的属性r是可选的。但是SpreadsheetGear也是因为如果Excel本身使用r属性,那么没有理由不使用它

如果无法以Apache POI可以直接读取的格式获取testfile.xlsx,则必须使用底层对象。以下内容适用于testfile.xlsx:

import org.apache.poi.xssf.usermodel.*;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.ss.util.*;
import org.apache.poi.openxml4j.exceptions.InvalidFormatException;

import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.FileInputStream;
import java.io.InputStream;

import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData;
import org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow;

import java.util.List;

class Testfile {

 public static void main(String[] args) {
  try {

   InputStream inp = new FileInputStream("testfile.xlsx");
   Workbook wb = WorkbookFactory.create(inp);

   Sheet sheet = wb.getSheetAt(0);

   System.out.println(sheet.getFirstRowNum());

   CTWorksheet ctWorksheet = ((XSSFSheet)sheet).getCTWorksheet();

   CTSheetData ctSheetData = ctWorksheet.getSheetData();

   List<CTRow> ctRowList = ctSheetData.getRowList();

   Row row = null;
   Cell[] cell = new Cell[2];

   for (CTRow ctRow : ctRowList) {
    row = new MyRow(ctRow, (XSSFSheet)sheet);
    cell[0] = row.getCell(0);
    cell[1] = row.getCell(1);
    if (cell[0] != null && cell[1] != null && cell[0].toString() != "" && cell[1].toString() != "") 
       System.out.println(cell[0].toString()+"\t"+cell[1].toString());
   }

  } catch (InvalidFormatException ifex) {
  } catch (FileNotFoundException fnfex) {
  } catch (IOException ioex) {
  }
 }
}

class MyRow extends XSSFRow {
 MyRow(org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow row, XSSFSheet sheet) {
  super(row, sheet);
 }
}
我使用了:

org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow 它们是Apache POI二进制发行版POI-bin-3.10.1-20140818的一部分,在POI-ooxml-schemas-3.10.1-20140818.jar中有

有关文档,请参阅


我已经扩展了XSSFRow,因为我们不能直接使用XSSFRow构造函数,因为它具有受保护的访问权限

这绝对不是一种需要HSSF框架的旧格式。我希望有人能告诉我文件有什么问题,因为2010年的文件肯定可以被框架读取。你确定你的数据不在表1或表2中吗?testfile.xlsx是用SpreadsheetGear 7.1.1.120创建的。使用能够处理ZIP存档的软件打开XLSX文件,并查看/xl/workbook.xml以查看该文件。在工作表/工作表?.xml文件中,请注意所有行元素都没有行号。如果我在第一行标记中添加一个行号,比如ApachePOI就可以读取这一行。这肯定不是一种需要HSSF框架的旧格式。我希望有人能告诉我文件有什么问题,因为2010年的文件肯定可以被框架读取。你确定你的数据不在表1或表2中吗?testfile.xlsx是用SpreadsheetGear 7.1.1.120创建的。使用能够处理ZIP存档的软件打开XLSX文件,并查看/xl/workbook.xml以查看该文件。在工作表/工作表?.xml文件中,请注意所有行元素都没有行号。如果我在第一行标记中添加一个行号,比如ApachePOI可以读取这一行。有一个选项可以告诉SpreadsheetGear包含此属性。默认情况下不包括它,因为它在技术上是可选的,Excel在读取此类文件时没有问题。省略它可以显著提高压缩比,从而减少文件大小和处理时间,特别是对于较大的工作簿文件。J ust要详细说明电子表格设备省略了可选的r属性,请参阅。有一个选项可以告诉SpreadsheetGear包含此属性。默认情况下不包括它,因为它在技术上是可选的,Excel在读取此类文件时没有问题。省略它可以显著提高压缩比,从而减少文件大小和处理时间,特别是对于较大的工作簿文件。