Database
 sql >> Datenbank >  >> RDS >> Database

So erstellen Sie ein Excel-Dokument aus einem Java-Programm mit Apache POI

Der Apache-POI ist eine beliebte Open-Source-Bibliothek, die zum Lesen, Schreiben und Bearbeiten von MS Office- und Open Office-Dateien mithilfe von Java-Code verwendet wird. Die Bibliothek ist eines der vielen Open-Source-Produkte, die von der Apache Software Foundation gepflegt werden (ASF) zur Java-Community beigetragen. Die Bibliothek enthält Klassen und Methoden zum Decodieren von Dateiformaten basierend auf Open Office XML-Standards und Microsoft OLE2. Obwohl die Bibliothek in der Lage ist, Word-, Excel-Tabellen- und PowerPoint-Dateien zu manipulieren, konzentriert sich dieser Artikel hauptsächlich auf Tabellenkalkulationsdokumente, nur um es kurz zu machen.

Lernen Sie JAVA und starten Sie noch heute Ihre kostenlose Testversion!

Die Apache-POI-Bibliothek

Interessanterweise steht POI im Namen Apache POI für „Poor Obfuscation Implementation“, und das Ziel der Bibliothek ist die Bereitstellung von Java-APIs zur Manipulation verschiedener Dateiformate auf der Grundlage der Office Open XML-Standards (OOXML) und des OLE 2 Compound Document-Formats von Microsoft (OLE2). Kurz gesagt ermöglicht dies das Lesen und Schreiben von MS Excel-, MS Word- und MS PowerPoint-Dateien unter Verwendung von Java-Code. Die meisten Microsoft Office-Dateien – wie XLS-, DOC-, PPT- und MFC-Serialisierungs-API-basierte Dateiformate – basieren auf dem OLE2-Standard. Das OLE ist im Grunde eine proprietäre Technik entwickelt von Microsoft und stellt das Format zum Verknüpfen von Objekten und zum Einbetten von Objekten in Containerdokumente bereit. Das erste Format wird als OLE1.0-Format bezeichnet, bei dem die Daten des verknüpften Objekts und des eingebetteten Objekts als eine Folge von Bytes innerhalb des Containerdokuments angeordnet sind. Die zweite Version, das OLE2.0-Format, nutzt die OLE-Compound-File-Technologie (MS-CFB), bei der die verknüpften Objekt- oder eingebetteten Objektdaten in diesem Speicher in Form von OLE-Compound-File-Stream-Objekten enthalten sind. Weitere Informationen hierzu finden Sie unter OLE1.0- und OLE2.0-Formate. Die Apache POI-Bibliothek bietet Bibliotheks-APIs für das OLE2-Dateisystem namens POIFS und OLE2-Dokumenteigenschaften namens HPSF.

Apache-POI-Komponenten

Die Apache POI-Bibliothek stellt Klassen und Methoden bereit, um mit OLE2 Compound Documents von MS Office zu arbeiten. Hier ist ein kurzer Überblick über die am häufigsten verwendeten:

  • POIFS für OLE2-Dokumente:Das POIFS steht für Poor Obfuscation Implementation File System . Dies ist das grundlegende POI-Element, das in der Bibliothek implementiert ist, um OLE2 Compound Document zu portieren. Es unterstützt Lese- und Schreibfunktionen für das binäre Nicht-XML-Microsoft Office-Format. Alle APIs der POI-Bibliothek bauen darauf auf.
  • HSSF und XSSF:HSSF steht für Horrible Spread Sheet Format . Es ist ein Java-Implementierungsport für das Excel 97-Dateiformat oder für .xls-Dateien. XSSF steht für XML Spread Sheet Format und es ist ein Port für das OOXML-Dateiformat oder das .xlsx-Dateiformat.
  • HWPF und XWPF:HWPF steht für Horrible Word Processor Format . Es ist ein eingeschränkter schreibgeschützter Port für das ältere Word 6- oder Word 95-Dateiformat. XWPF steht für XML Word Processor Format . Es ist ein Java-Implementierungsport für das Dateiformat Word 2007 .docx. Beide Implementierungen unterstützen eingeschränkte Funktionalität.
  • HSLF und XSLF:HSLF steht für Horrible Slide Layout Format . XSLF steht für XML Slide Layout Format . Beide bieten Lese-, Schreib-, Erstellungs- und Änderungsfunktionen für PowerPoint-Präsentationen, während HSLF das PowerPoint 97-Format und XSLF spätere Versionen unterstützt.
  • HPSF :HPSF steht für Horrible Property Set Format . Es wird insbesondere verwendet, um mit Dokumenteigenschaften zu arbeiten, wie z. B. das Festlegen von Titel, Kategorie, Autor, Änderungsdatum usw. eines Dokuments
  • HDGF und XDGF:HDGF steht für Horrible Diagram Format . Diese Komponente enthält Klassen zum Arbeiten mit dem binären Dateiformat von Visio. Es bietet schreibgeschützte Low-Level-APIs für den Zugriff auf Visio-Dokumente und VSD-Dateien. XDGF steht für XML-Diagrammformat . Es ist für das Visio XML-Dateiformat oder VSDX-Dateien.
  • HPBF :Das HPBF steht für Horrible Publisher Format . Es ist eine eingeschränkte Java-Portierung, um mit dem MS Publisher-Dateiformat zu arbeiten.

Die Akronyme klingen humorvoll, weil diese Dateisysteme geschlossen werden sollten und Microsoft sein Bestes gab, um den Code zu verschleiern, sodass sie nicht nur schwer verständlich, sondern auch schwer rückzuentwickeln sind. Aber die Entwickler von Apache haben es mit Leichtigkeit gehackt und erfolgreich zurückentwickelt. Vielleicht, als Zeichen der Freude oder der völligen Verurteilung des geschlossenen Systems, haben sie sie scherzhaft als solche bezeichnet.

Mit HSSF- und XSSF-Dateien arbeiten

Die HSSF- und XSSF-Komponenten der Apache-Bibliothek bieten drei Modelle für den Zugriff auf ein Tabellenkalkulationsdokument gemäß der HSSF- und XSSF-Dokumentation. Sie sind:

  • Untergeordnete Strukturen für besondere Bedürfnisse
  • Die Eventmodel-APIs für den schreibgeschützten Zugriff auf Excel-Dokumente
  • Die Benutzermodell-APIs zum Erstellen, Lesen und Ändern von Excel-Dateien

Die eingeschränkten Ereignismodell-APIs können nur zum Lesen von Tabellenkalkulationsdaten verwendet werden. Diese APIs befinden sich im org.apache.poi.hssf.eventusermodel Paket und org.apache.poi.xssf.eventusermodel Paket, wobei das erste verwendet wird, um Daten aus der .xls zu lesen Dateiformat und das zweite wird verwendet, um Daten aus .xlsx zu lesen Dateiformat.

Das Benutzermodell ist viel flexibler und einfacher zu verwenden; Es kann ein Excel-Tabellendokument lesen, schreiben, erstellen und ändern. Aber es hat einen viel höheren Speicherbedarf als das Low-Level-Ereignismodell.

Außerdem hat der Zugriff auf und die Bearbeitung des neueren OOXML-basierten Dateiformats mit XSSF einen viel höheren Speicherbedarf als die alten HSSF-unterstützten Binärdateien.

Ab POI 3.5 wurde das HSSF- und XSSF-Modell in das SS-Modell integriert, eher optimiert, um für beide Modelle zu funktionieren. Es ist eher eine Anpassung des Namens als eine echte Änderung. In gewisser Weise können wir sagen, dass SS=HSSF+XSSF.

Migration von Datenbanktabellendaten in eine Excel-Tabelle

Hier erstellen wir ein einfaches Hilfsprogramm, um einige Datenbankdaten in eine Excel-Tabelle zu migrieren. Dies kann auch so angepasst werden, dass es mit anderen Methoden funktioniert, z. B. mit der Migration von Excel-Daten in eine Datenbanktabelle. Dies sei dem Leser als Übung überlassen. Das Programm ist einfach und selbsterklärend. Besuchen Sie die Apache POI-Dokumentation für detaillierte Informationen zu Klassen oder Methoden. Um das folgende Beispiel auszuprobieren, haben wir Folgendes verwendet:

  • JDK 8
  • MS Excel 2007
  • Intellij IDEA IDE
  • Apache-POI 3.17
  • Apache Derby 10.14

Besuchen Sie die entsprechenden Dokumente und Hilfedateien zum Einrichten des Projekts. Hier ist der Inhalt der von uns verwendeten Maven pom.xml-Datei.

<project 
   xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
   xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
   http://maven.apache.org/xsd/maven-4.0.0.xsd">
   <modelVersion>4.0.0</modelVersion>

   <groupId>com.mano.examples</groupId>
   <artifactId>apache-poi-demo</artifactId>
   <version>1.0-SNAPSHOT</version>
   <packaging>jar</packaging>

   <name>apache-poi-demo</name>
   <url>http://maven.apache.org</url>

   <properties>
      <project.build.sourceEncoding>
         UTF-8
      </project.build.sourceEncoding>
   </properties>

   <build>
      <plugins>
         <plugin>
            <artifactId>
               maven-compiler-plugin
            </artifactId>
            <version>3.7.0</version>
            <configuration>
               <source>1.8</source>
               <target>1.8</target>
            </configuration>
         </plugin>
      </plugins>
   </build>

   <dependencies>
      <dependency>
         <groupId>junit</groupId>
         <artifactId>junit</artifactId>
         <version>3.8.1</version>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact
         /org.apache.maven.plugins/maven-compiler-plugin -->
      <dependency>
         <groupId>org.apache.maven.plugins</groupId>
         <artifactId>maven-compiler-plugin</artifactId>
         <version>3.7.0</version>
      </dependency>

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

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

      <!-- https://mvnrepository.com/artifact/
         org.apache.derby/derby -->
      <dependency>
         <groupId>org.apache.derby</groupId>
         <artifactId>derby</artifactId>
         <version>10.14.1.0</version>
         <scope>test</scope>
      </dependency>

      <!-- https://mvnrepository.com/artifact/
         org.apache.derby/derbyclient -->
      <dependency>
         <groupId>org.apache.derby</groupId>
         <artifactId>derbyclient</artifactId>
         <version>10.14.1.0</version>
      </dependency>

   </dependencies>
</project>

Auflistung 1: pom.xml

Vor dem Ausführen des Dienstprogramms wird eine Datenbanktabelle mit einigen Dummy-Datensätzen erstellt. Hier ist der Code dieser Datei.

package com.mano.examples;

import java.sql.*;


public class DummyDatabase {

   public static void createDummyDatabase()
         throws SQLException {
      Connection con=DriverManager.getConnection
         ("jdbc:derby:D:/temp/dummy;create=true");
      Statement stmt=con.createStatement();
      stmt.executeUpdate("drop table semester2");
      stmt.executeUpdate("CREATE TABLE semester2(STUDENT_ID int,
         CARCH INT, DCE INT, WEBTECH INT, JAVA INT, SAD_MIS INT,
         PRIMARY KEY(STUDENT_ID))");

      // Insert 2 rows
      stmt.executeUpdate("insert into semester2
         values (23567932,56,78,97,58,85)");
      stmt.executeUpdate("insert into semester2
         values (47250001,96,34,75,68,12)");
      stmt.executeUpdate("insert into semester2
         values (99568955,45,68,69,78,29)");
      stmt.executeUpdate("insert into semester2
         values (89376473,75,23,56,89,47)");
      stmt.executeUpdate("insert into semester2
         values (29917740,85,78,55,15,48)");
      stmt.executeUpdate("insert into semester2
         values (85776649,23,56,78,25,69)");
      stmt.executeUpdate("insert into semester2
         values (38846455,68,95,78,53,48)");
      stmt.executeUpdate("insert into semester2
         values (40028826,63,56,48,59,75)");
      stmt.executeUpdate("insert into semester2
         values (83947759,85,54,69,36,89)");
      stmt.executeUpdate("insert into semester2
         values (92884775,78,59,25,48,69)");
      stmt.executeUpdate("insert into semester2
         values (24947389,12,10,14,54,68)");
      stmt.executeUpdate("insert into semester2
         values (77399465,44,33,26,88,77)");

      // Query
      ResultSet rs = stmt.executeQuery
      ("SELECT * FROM semester2");

      // Print out query result
      while (rs.next()) {
         System.out.printf
               ("%dt%dt%dt%dt%dt%dn",
            rs.getLong("STUDENT_ID"),
            rs.getInt("CARCH"),
            rs.getInt("DCE"),
            rs.getInt("WEBTECH"),
            rs.getInt("JAVA"),
            rs.getInt("SAD_MIS"));
      }
      stmt.close();
      con.close();
   }
}

Auflistung 2: DummyDatabase.java.

Dies ist das Dienstprogramm, von dem wir sprechen. Der Code war in großer Eile geschrieben und die Struktur nicht sehr elegant. Es funktioniert jedoch. Restrukturieren oder optimieren Sie es, wie Sie es für richtig halten.

package com.mano.examples;

import org.apache.poi.hssf.usermodel.HSSFWorkbook;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;


import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.sql.*;

public class SSFile {

   private static String[] header={"STUDENT_ID",
      "CARCH", "DCE", "WEBTECH", "JAVA",
      "SAD_MIS", "TOTAL", "AVERAGE"};

   public static void databaseToExcel(File file)
         throws IOException, SQLException {
      Workbook workbook = null;
      if (file.getName().endsWith(".xls"))
         workbook = new HSSFWorkbook();
      else if (file.getName().endsWith(".xlsx"))
         workbook = new XSSFWorkbook();
      else {
         System.out.println("Invalid filename!");
         return;
      }
      Sheet sheet = workbook.createSheet();
      Connection con = DriverManager.getConnection
         ("jdbc:derby:D:/temp/dummy;create=true");
      Statement stmt = con.createStatement();
      ResultSet rs = stmt.executeQuery("SELECT * FROM semester2");



      Row rr = sheet.createRow(0);
      for(int i=0;i<header.length;i++){
         createHeaderCell(rr, (short) i, header[i]);
      }

      int i = 1;
      while (rs.next()) {
         rr = sheet.createRow(i++);
         for(int j=0;j<header.length-2;j++){
            createDataCell(rr, (short) j,
               rs.getLong(header[j]));
         }
      }
      rr = sheet.getRow(1);
      Cell total = rr.createCell(6);
      total.setCellType(CellType.FORMULA);
      total.setCellFormula("SUM(B2:F2)");
      Cell avg = rr.createCell(7);
      avg.setCellType(CellType.FORMULA);
      avg.setCellFormula("AVERAGE(B2:F2)");

      FileOutputStream outFile = new
         FileOutputStream(file);
      workbook.write(outFile);
      outFile.flush();
      outFile.close();
      stmt.close();
      con.close();
   }

   private static void createHeaderCell(Row row,
         short col, String cellValue) {
      Cell c = row.createCell(col);
      c.setCellValue(cellValue);
   }

   private static void createDataCell(Row row,
         short col, Number cellValue) {
      Cell c = row.createCell(col);
      c.setCellType(CellType.NUMERIC);
      c.setCellValue(cellValue.doubleValue());
   }
}

Auflistung 3: SSFile.java

Dies ist das Bedienfeld, von dem aus das Dienstprogramm aufgerufen wird.

package com.mano.examples;

import java.io.File;
import java.io.IOException;
import java.sql.SQLException;

public class App
{
   public static void main( String[] args )
         throws IOException,SQLException{
      // DummyDatabase.createDummyDatabase();
      SSFile.databaseToExcel(new
         File("d://temp//test1.xls"));
   }
}

Auflistung 4 :App.java

Vor dem Laufen…

Stellen Sie sicher, dass die Datei test1.xls oder test1.xlsx Dateien existieren nicht in d://temp Verzeichnis vor dem Ausführen des Programms, da das Programm die gleichnamige Datei in dem Verzeichnis, in dem die Datei erstellt werden soll, weder überschreibt noch überprüft. Stellen Sie dies bei jedem Programmlauf sicher; Andernfalls gibt der Code eine böse Fehlermeldung aus. Sie können den Code jedoch anpassen, um ihn zu überprüfen.

Schlussfolgerung

Es gibt eine weitere Alternative zur Arbeit mit Tabellenkalkulationen, wie die Apache POI-Dokumentation über den Cocoon-Serializer vorschlägt, obwohl dieser indirekt immer noch HSSF verwendet. Cocoon kann jede XML-Datenquelle serialisieren, indem es das Stylesheet anwendet und den Serializer bestimmt. Das HSSF- und XSSF-Modell ist ziemlich leistungsfähig und bietet eine Reihe von Klassen und Methoden, um mit verschiedenen Aspekten eines Excel-Dokuments umzugehen. Dieser Artikel hat versucht, einen Eindruck davon zu vermitteln, was wir mit Apache POI machen können. Wir müssen oft ein Dienstprogramm schreiben, um eine Brücke zwischen einem offenen und einem geschlossenen System zu schlagen. Apache POI kann unseren Zweck definitiv als einzigartig in seiner Art erfüllen.

Referenzen

  • Apache POI – die Java-API für Microsoft-Dokumente
  • POI-HSSF und POI-XSSF – Java-API für den Zugriff auf Dateien im Microsoft Excel-Format