Apache POI - Excel-Datei einlesen

Aus Byte-Welt Wiki
Version vom 3. März 2019, 19:11 Uhr von L-ectron-X (Diskussion | Beiträge) (Die Seite wurde neu angelegt: „Kategorie:Codeschnipsel Mit dem Java-Framework Apache POI kann man recht komfortabel Excel-Dateien auslesen und erzeugen (schreiben). Hier ein Beispie…“)
(Unterschied) ← Nächstältere Version | Aktuelle Version (Unterschied) | Nächstjüngere Version → (Unterschied)
Zur Navigation springenZur Suche springen

Mit dem Java-Framework Apache POI kann man recht komfortabel Excel-Dateien auslesen und erzeugen (schreiben).

Hier ein Beispiel zum Auslesen einer beliebigen Excel-Datei. Das heißt, wir verarbeiten das binäre Format (.xls) sowie das auf XML basierende Format .xslx .

Excel-Datei einlesen

Wir schreiben uns zunächst eine Klasse, die zwei private Methoden implementiert, die die beiden Dateitypen separat verarbeiten: <syntaxhighlight lang="java" line="true"> import org.apache.poi.EncryptedDocumentException; import org.apache.poi.hssf.usermodel.HSSFWorkbook; import org.apache.poi.openxml4j.exceptions.InvalidFormatException; import org.apache.poi.openxml4j.opc.OPCPackage; import org.apache.poi.poifs.filesystem.POIFSFileSystem; import org.apache.poi.ss.usermodel.Cell; import org.apache.poi.ss.usermodel.CreationHelper; import org.apache.poi.ss.usermodel.DateUtil; import org.apache.poi.ss.usermodel.FormulaEvaluator; import org.apache.poi.ss.usermodel.Row; import org.apache.poi.ss.usermodel.Sheet; import org.apache.poi.ss.usermodel.Workbook; import org.apache.poi.ss.util.WorkbookUtil; import org.apache.poi.xssf.usermodel.XSSFWorkbook;

/**

* ExcelFileProxy liest die Excel-Datei ein und erzeugt ein tabellarisches
* Abbild der Arbeitsmappe in Form von verschachtelten Listen.
*
* @author Gernot Segieth
*/

public class ExcelFileReader {

   private Workbook workbook
   /**
    * Liest die ihm übergebene Excel-Datei ein und erzeugt ein tabellarisches Abbild
    * davon.
    *
    * @param excelFile Die einzulesene Excel-Datei
    * @throws java.lang.ClassNotFoundException wenn eine Klasse nicht gefunden
    * wurde
    * @throws java.io.IOException wenn die Datei nicht eingelesen werde konnte
    * @throws org.apache.poi.openxml4j.exceptions.InvalidFormatException wenn
    * es Probleme mit dem Format der Datei oder der Verschlüsselung gibt
    */
   public ExcelFileReader(File excelFile) throws ClassNotFoundException, IOException, InvalidFormatException {
       createWorkbook(excelFile);
   }
   private void readHSSFWorkbook(File file) throws IOException {
       POIFSFileSystem fs = new POIFSFileSystem(file);
       workbook = new HSSFWorkbook(fs.getRoot(), true);
       fs.close();
   }
   private void readXSSFWorkbook(File file) throws InvalidFormatException, IOException {
       OPCPackage pkg = OPCPackage.open(file);
       workbook = new XSSFWorkbook(pkg);
       pkg.close();
   }

} </syntaxhightlight>

Anschließend eine fügen wir die bereits im Konstruktor aufgerufene Methode, die die Dateitypen unterscheidet, unsere eben erstellten Methoden aufruft und damit das Workbook aus der übergebenen Datei (File erzeugt, ein. <syntaxhighlight lang="java" line="true">

   private void createWorkbook(File file) throws ClassNotFoundException, IOException, InvalidFormatException {
       String filename = file.getName().toLowerCase();
       try {
           if (filename.endsWith(".xls")) {
               readHSSFWorkbook(file);
           } else if (filename.endsWith(".xlsx")) {
               readXSSFWorkbook(file);
           } else {
               throw new IllegalArgumentException("Ausnahmefehler: Die übergebene Datei " + file.getName() + " ist keine valide Microsoft Excel-Datei (*.xls bzw. *.xlsx)!");
           }
       } catch (IOException ioe) {
           System.err.println(getClass().getName() + ": " + ioe);
           throw new IOException("Ausnahmefehler: Die Datei " + file.getName() + " konnte nicht eingelesen werden!");
       } catch (EncryptedDocumentException ede) {
           System.err.println(getClass().getName() + ": " + ede);
           throw new EncryptedDocumentException("Ausnahmefehler: Die Datei " + file.getName() + " ist mit einem Passwort geschützt und kann daher nicht geöffnet werden!");
       } catch (NoClassDefFoundError err) {
           System.err.println(getClass().getName() + ": " + err.toString());
           throw new ClassNotFoundException("Schwerer Ausnahmefehler: Klassendefinition nicht gefunden!\nPrüfen Sie die Programmdateien und externen Bibliotheken auf Vollständigkeit!");
       }
   }

</syntaxhightlight>

Damit haben wir den Code zum Öffnen und Einlesen von Excel-Dateien schon geschrieben.

Workbook auslesen

Eine Excel-Datei wird als Workbook bezeichnet und besteht aus mindestens einem Arbeitsblatt. Wir sprechen hier vom Interface Sheet. Ein Arbeitsblatt enthält wiederum Zellen, die in POI als Spalten in Zeilen organisiert sind und mit dem Interface Cell repräsentiert werden. Eine Zelle kann verschiedene Zelltypen haben, die in der Enumeration CellType aufgelistet sind.

Ein Arbeitsblatt besteht also aus Zeilen, über die in einer Schleife iteriert werden kann.

=Workbook vollständig auslesen

In diesem Abschnitt schreiben wir uns den Code zum vollständigen Auslesen eines Arbeitsblattes einer Excel-Datei. <syntaxhighlight lang="java" line="true">

   /**
    * Gibt den Inhalt des übergebenen Tabellenblattes in einer Liste
    * die Listen mit Objekten speichert, zurück.
    *
    * @param sheetIndex der Index des Tabellenblattes
    * @return eine Liste aus Listen (Zeilen mit Spalten)
    */
   public List<List<?>> getSheetContent(int sheetIndex) {
       evaluator = workbook.getCreationHelper().createFormulaEvaluator();
       Sheet sheet = workbook.getSheetAt(sheetIndex);
       List<List<?>> sheetData = new ArrayList<>();
       for (Row row : sheet) {
           if (row != null) {
               List<Object> rowData = new ArrayList<>();
               boolean isEmptyRow = true; //Zeile erstmal als leer ansehen
               for (Cell cell : row) {
                   if (cell != null) {
                       switch (cell.getCellType()) {
                           case STRING:
                               String string = cell.getRichStringCellValue().getString();
                               if (string.isEmpty()) {
                                   rowData.add(null);
                               } else {
                                   rowData.add(string.trim());
                                   isEmptyRow = false;
                               }
                               break;
                           case NUMERIC:
                               if (DateUtil.isCellDateFormatted(cell)) {
                                   Date date = cell.getDateCellValue();
                                   if (date.toString().isEmpty()) {
                                       rowData.add(null);
                                   } else {
                                       rowData.add(date);
                                       isEmptyRow = false;
                                   }
                               } else {
                                   Number number = cell.getNumericCellValue();
                                   if (number.toString().isEmpty()) {
                                       rowData.add(null);
                                   } else {
                                       rowData.add(number);
                                       isEmptyRow = false;
                                   }
                               }
                               break;
                           case BOOLEAN:
                               Boolean bool = (cell.getBooleanCellValue());
                               if (bool.toString().isEmpty()) {
                                   rowData.add(null);
                               } else {
                                   rowData.add(bool);
                                   isEmptyRow = false;
                               }
                               break;
                           case _NONE:
                           case FORMULA:
                           case BLANK:
                           case ERROR:
                           default:
                               rowData.add(null);
                               break;
                       }
                   } else {
                       rowData.add(null);
                   }
               }
               if (!isEmptyRow) { //leere Zeilen nicht aufnehmen
                   sheetData.add(rowData);
               }
           }
       }
       return sheetData;
   }

</syntaxhightlight>

Workbook teilweise auslesen

Baustelle.png Dieser Beitrag wird derzeit noch bearbeitet. Der Text ist deshalb unvollständig und kann Fehler oder ungeprüfte Aussagen enthalten.