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="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>
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