POI Apache to popularna biblioteka open source używana do czytania, pisania i manipulowania plikami MS Office i Open Office za pomocą kodu Java. Biblioteka jest jednym z wielu produktów open source utrzymywanych przez Apache Software Foundation (ASF) przyczynił się do rozwoju społeczności Java. Biblioteka zawiera klasy i metody dekodowania formatów plików w oparciu o standardy Open Office XML i Microsoft OLE2. Chociaż biblioteka jest w stanie manipulować plikami Word, Excel i PowerPoint, ten artykuł skupia się głównie na dokumentach arkuszy kalkulacyjnych, tylko po to, by był zwięzły.
Naucz się języka JAVA i rozpocznij bezpłatny okres próbny już dziś!
Biblioteka POI Apache
Co ciekawe, w nazwie Apache POI POI oznacza „Poor Obfuscation Implementation”, a celem biblioteki jest zapewnienie interfejsów Java API do manipulowania różnymi formatami plików w oparciu o standardy Office Open XML (OOXML) i format dokumentów OLE 2 firmy Microsoft (OLE2). Krótko mówiąc, umożliwia to odczytywanie i zapisywanie plików MS Excel, MS Word i MS PowerPoint za pomocą kodu Java. Większość plików pakietu Microsoft Office — takich jak formaty plików oparte na interfejsie API serializacji XLS, DOC, PPT i MFC — jest opartych na standardzie OLE2. Zasadniczo OLE jest zastrzeżoną techniką, opracowaną przez firmę Microsoft i zapewnia format łączenia obiektów i osadzania obiektów w dokumentach kontenerów. Pierwszy format nazywa się formatem OLE1.0, w którym obiekt połączony i osadzone dane obiektu są ułożone jako sekwencja bajtów w dokumencie kontenera. Druga wersja, format OLE2.0, wykorzystuje technologię OLE Compound File Technology (MS-CFB), w której połączony obiekt lub osadzone dane obiektu są zawarte w tym magazynie w postaci obiektów OLE Compound File Stream. Więcej informacji na ten temat można znaleźć w formatach OLE1.0 i OLE2.0. Biblioteka Apache POI zapewnia interfejsy API bibliotek dla systemu plików OLE2 o nazwie POIFS i Właściwości dokumentu OLE2 o nazwie HPSF.
Komponenty POI Apache
Biblioteka Apache POI udostępnia klasy i metody do pracy ze złożonymi dokumentami OLE2 pakietu MS Office. Oto krótki przegląd najczęściej używanych:
- POIFS dla dokumentów OLE2:POIFS oznacza Poor Obfuscation Implementation File System . Jest to podstawowy element POI zaimplementowany w bibliotece do portu dokumentu złożonego OLE2. Obsługuje funkcję odczytu i zapisu dla binarnego formatu Microsoft Office innego niż XML. Wszystkie API biblioteki POI są zbudowane na tym.
- HSSF i XSSF:HSSF oznacza okropny format arkusza kalkulacyjnego . Jest to port implementacji języka Java dla formatu pliku Excel 97 lub plików .xls. XSSF oznacza format arkusza kalkulacyjnego XML i jest to port dla formatu pliku OOXML lub formatu pliku .xlsx.
- HWPF i XWPF:HWPF oznacza Straszny format edytora tekstu . Jest to ograniczony port tylko do odczytu dla starszego formatu plików Word 6 lub Word 95. XWPF oznacza format edytora tekstu XML . Jest to port implementacji języka Java dla formatu pliku Word 2007 .docx. Obie implementacje obsługują ograniczoną funkcjonalność.
- HSLF i XSLF:HSLF oznacza okropny format układu slajdów . XSLF oznacza Format układu slajdów XML . Oba zapewniają możliwość odczytu, zapisu, tworzenia i modyfikowania prezentacji PowerPoint, podczas gdy HSLF obsługuje format PowerPoint 97, a XSLF obsługuje późniejsze wersje.
- HPSF :HPSF oznacza Straszny format zestawu właściwości . Jest szczególnie używany do pracy z właściwościami dokumentu, takimi jak ustawianie tytułu, kategorii, autora, daty modyfikacji i tak dalej dokumentu
- HDGF i XDGF:HDGF oznacza Straszny format diagramu . Ten składnik zawiera klasy do pracy z binarnym formatem pliku Visio. Zapewnia niskopoziomowe interfejsy API tylko do odczytu umożliwiające dostęp do dokumentów Visio i plików VSD. XDGF oznacza Format diagramu XML . Jest przeznaczony dla formatu pliku Visio XML lub plików VSDX.
- HPBF :HPBF oznacza Straszny format wydawcy . Jest to ograniczony port Java do pracy z formatem plików MS Publisher.
Akronimy brzmią humorystycznie, ponieważ te systemy plików miały zostać zamknięte, a Microsoft dołożył wszelkich starań, aby zaciemnić kod, tak aby były nie tylko trudne do zrozumienia, ale także trudne do odtworzenia. Ale programiści z Apache z łatwością zhakowali go i pomyślnie wykonali inżynierię wsteczną. Być może, na znak radości lub całkowitego potępienia zamkniętego systemu, żartobliwie nazwali je takimi.
Praca z plikami HSSF i XSSF
Komponenty HSSF i XSSF biblioteki Apache zapewniają trzy modele dostępu do dokumentu arkusza kalkulacyjnego zgodnie z dokumentacją HSSF i XSSF. Są to:
- Struktury niskiego poziomu dla specjalnych potrzeb
- Interfejsy API modelu zdarzeń dla dostępu tylko do odczytu do dokumentów Excel
- Interfejsy API modelu użytkownika do tworzenia, czytania i modyfikowania plików Excel
Ograniczone interfejsy API modelu zdarzeń mogą być używane tylko do odczytu danych z arkusza kalkulacyjnego. Te interfejsy API znajdują się w org.apache.poi.hssf.eventusermodel pakiet i org.apache.poi.xssf.eventusermodel pakiet, w którym pierwszy służy do odczytu danych z pliku .xls format pliku, a drugi służy do odczytywania danych z pliku .xlsx format pliku.
Model użytkownika jest znacznie bardziej elastyczny i łatwiejszy w użyciu; może czytać, pisać, tworzyć i modyfikować dokument arkusza kalkulacyjnego Excel. Ale ma znacznie większe zużycie pamięci niż model zdarzeń niskiego poziomu.
Ponadto dostęp do nowszego formatu pliku opartego na OOXML i manipulowanie nim za pomocą XSSF ma znacznie większe zużycie pamięci niż stare pliki binarne obsługiwane przez HSSF.
Począwszy od POI 3.5, modele HSSF i XSSF zostały połączone z modelem SS, raczej dostosowane, aby działały z obydwoma modelami. To bardziej zmiana nazwy niż prawdziwa zmiana. W pewnym sensie możemy powiedzieć, że SS=HSSF+XSSF.
Migracja danych tabeli bazy danych do arkusza kalkulacyjnego Excel
Tutaj stworzymy prosty program narzędziowy do migracji niektórych danych z bazy danych do arkusza Excel. Można to również dostosować, aby działał z innymi sposobami, takimi jak migracja danych programu Excel do tabeli bazy danych. To jest ćwiczenie dla czytelnika. Program jest prosty i zrozumiały. Odwiedź dokumentację Apache POI, aby uzyskać szczegółowe informacje na temat klas lub metod. Aby wypróbować następujący przykład, użyliśmy następującego:
- JDK 8
- MS Excel 2007
- Idea pomysłu Intellij
- Apache POI 3.17
- Apache Derby 10.14
Odwiedź odpowiednie dokumenty i pliki pomocy, aby skonfigurować projekt. Oto zawartość pliku Maven pom.xml, którego użyliśmy.
<project
xmlns:xsi="https://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="https://maven.apache.org/POM/4.0.0
https://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>https://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>
Lista 1: pom.xml
Tabela bazy danych jest tworzona z niektórymi fikcyjnymi rekordami przed uruchomieniem programu narzędziowego. Oto kod tego pliku.
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();
}
}
Lista 2: DummyDatabase.java.
To jest program narzędziowy, o którym mówimy. Kod został napisany w dużym pośpiechu, a struktura niezbyt elegancka. Jednak to działa. Zmień lub dostosuj go według własnego uznania.
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());
}
}
Lista 3: Plik SSFile.java
To jest panel sterowania, z którego wywoływany jest program narzędziowy.
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"));
}
}
Lista 4 :Aplikacja.java
Przed uruchomieniem…
Upewnij się, że plik test1.xls lub test1.xlsx pliki nie istnieją w d://temp katalogu przed uruchomieniem programu, ponieważ program nie nadpisuje ani nie sprawdza pliku o tej samej nazwie w katalogu, w którym plik ma zostać utworzony. Upewnij się o tym za każdym razem, gdy program jest uruchamiany; w przeciwnym razie kod wyświetla paskudny komunikat o błędzie. Możesz jednak poprawić kod, aby sprawdzić.
Wniosek
Istnieje inna alternatywa dla pracy z arkuszami kalkulacyjnymi, jak sugeruje dokumentacja Apache POI za pośrednictwem serializatora Cocoon, chociaż nadal używa on pośrednio HSSF. Cocoon może serializować dowolne źródło danych XML, stosując arkusz stylów i wyznaczając serializator. Model HSSF i XSSF jest dość potężny i udostępnia wiele klas i metod do obsługi różnych aspektów dokumentu Excel. W tym artykule staraliśmy się rzucić okiem na to, co możemy zrobić z Apache POI. Często musimy napisać program narzędziowy, aby pomost między systemem otwartym i zamkniętym. Apache POI z pewnością może służyć naszym celom jako jedyny w swoim rodzaju.
Referencje
- Apache POI – Java API dla Microsoft Documents
- POI-HSSF i POI-XSSF – Java API do uzyskiwania dostępu do plików w formacie Microsoft Excel