Tidak dapat membaca file Excel 2010 dengan Apache POI. Nomor Baris Pertama adalah -1

Saya mencoba testfile ini dengan Apache POI API (versi saat ini 3 -10-AKHIR). Kode tes berikut

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());
    }
}

menghasilkan nomor baris pertama menjadi -1 (dan baris yang ada kembali sebagai nol). File pengujian dibuat oleh Excel 2010 (saya tidak memiliki kendali atas bagian itu) dan dapat dibaca dengan Excel tanpa peringatan atau masalah. Jika saya membuka dan menyimpan file dengan versi Excel saya (2013) maka dapat terbaca dengan sempurna sesuai harapan.

Petunjuk apa pun tentang mengapa saya tidak dapat membaca file asli atau bagaimana saya bisa membacanya, sangat kami hargai.


person ratatosk    schedule 27.11.2014    source sumber
comment
Ini jelas bukan format lama yang memerlukan kerangka HSSF. Saya berharap menemukan seseorang yang dapat memberi tahu saya apa yang salah dengan file tersebut (karena file 2010 pasti dapat dibaca oleh kerangka kerja)   -  person ratatosk    schedule 27.11.2014
comment
Apakah Anda yakin data Anda tidak ada di Lembar 1 atau Lembar 2?   -  person Gagravarr    schedule 27.11.2014
comment
testfile.xlsx dibuat dengan SpreadsheetGear 7.1.1.120. Buka file XLSX dengan perangkat lunak yang dapat menangani arsip ZIP dan lihat /xl/workbook.xml untuk melihatnya. Pada file worksheets/sheet?.xml perlu diperhatikan bahwa semua elemen baris tanpa nomor baris. Jika saya memasukkan nomor baris di tag baris pertama seperti <row r="1"> maka Apache POI dapat membaca baris ini.   -  person Axel Richter    schedule 27.11.2014


Jawaban (1)


testfile.xlsx dibuat dengan "SpreadsheetGear 7.1.1.120". Buka file XLSX dengan perangkat lunak yang dapat menangani arsip ZIP dan lihat /xl/workbook.xml untuk melihatnya. Pada file worksheets/sheet?.xml perlu diperhatikan bahwa semua elemen baris tanpa nomor baris. Jika saya memasukkan nomor baris di tag baris pertama seperti <row r="1"> maka Apache POI dapat membaca baris ini.

Jika ditanya siapa yang harus disalahkan, maka jawabannya pasti Apache Poi dan SpreadsheetGear ;-). Apache POI karena atribut r pada elemen row bersifat opsional. Namun SpreadsheetGear juga karena tidak ada alasan untuk tidak menggunakan atribut r jika Excel sendiri yang pernah melakukannya.

Jika Anda tidak bisa mendapatkan testfile.xlsx dalam format yang dapat dibaca langsung oleh Apache POI, maka Anda harus bekerja dengan objek yang mendasarinya. Berikut ini berfungsi dengan testfile.xlsx Anda:

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);
 }
}

Saya telah menggunakan:

  • org.openxmlformats.schemas.spreadsheetml.x2006.main.CTWorksheet
  • org.openxmlformats.schemas.spreadsheetml.x2006.main.CTSheetData
  • org.openxmlformats.schemas.spreadsheetml.x2006.main.CTRow

Yang merupakan bagian dari Distribusi Biner Apache POI poi-bin-3.10.1-20140818 dan ada di dalamnya poi-ooxml-schemas-3.10.1-20140818.jar

Untuk dokumentasi lihat http://grepcode.com/snapshot/repo1.maven.org/maven2/org.apache.poi/ooxml-schemas/1.1/

Dan saya telah memperluas XSSFRow, karena kita tidak dapat menggunakan konstruktor XSSFRow secara langsung karena aksesnya dilindungi.

person Axel Richter    schedule 28.11.2014
comment
Sekadar untuk menguraikan penghilangan atribut r opsional oleh SpreadsheetGear, silakan lihat stackoverflow.com/questions/26634736/. Ada adalah opsi untuk memberitahu SpreadsheetGear agar menyertakan atribut ini. Ini tidak disertakan secara default karena (selain fakta bahwa ini opsional secara teknis dan Excel tidak memiliki masalah dalam membaca file seperti itu) menghilangkannya dapat secara dramatis meningkatkan rasio kompresi zip dan oleh karena itu mengurangi ukuran file serta waktu untuk memprosesnya, khususnya untuk file buku kerja yang lebih besar. - person Tim Andersen; 22.01.2015