Я пытаюсь использовать этот тестовый файл с API Apache POI (текущая версия 3 -1 0-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". Откройте файл XLSX с помощью программного обеспечения, которое может обрабатывать ZIP-архивы и посмотреть в /xl/workbook.xml
чтобы увидеть это. В файлах worksheets/sheet?.xml
следует заметить, что все элементы строк не имеют номеров строк. Если я поместил номер строки в первый тег строки, например <row r="1">
то apache POI может прочитать эту строку.
Если дело дойдет до вопроса, кто виноват в этом, тогда ответ, безусловно, будет и Apache Poi, и SpreadsheetGear ;-). Apache POI, поскольку атрибут r
в элементе row
является необязательным. Но SpreadsheetGear также потому, что нет причин не использовать атрибут r
если Excel сам это делает.
Если вы не можете получить файл testfile.xlsx в формате, который может читать Apache POI напрямую, тогда вы должны работать с базовыми объектами. Следующее работает с вашим 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. Которые являются частью бинарного дистрибутива POI Apache POI-bin-3.10.1-20140818 и существуют в пределах poi-ooxml-schemas-3.10.1-20140818.jar
Для документации см. Http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/
И я расширяю XSSFRow, потому что мы не можем использовать конструктор XSSFRow напрямую, поскольку он имеет защищенный доступ.