Apache POI är ett populärt bibliotek med öppen källkod som används för att läsa, skriva och manipulera MS Office- och Open Office-filer med hjälp av Java-kod. Biblioteket är en av många open source-produkter som underhålls av Apache Software Foundation (ASF) bidrog till Java-gemenskapen. Biblioteket innehåller klasser och metoder för att avkoda filformat baserade på Open Office XML-standarder och Microsoft OLE2. Även om biblioteket kan manipulera Word-, Excel-kalkylblad och PowerPoint-filer, fokuserar den här artikeln huvudsakligen på kalkylarksdokument, bara för att göra den kort.
Lär dig JAVA och starta din gratis provperiod idag!
Apache POI-biblioteket
Intressant nog, i namnet Apache POI, står POI för "Poor Obfuscation Implementation" och målet med biblioteket är att tillhandahålla Java API:er för att manipulera olika filformat baserat på Office Open XML-standarder (OOXML) och Microsofts OLE 2 Compound Document-format (OLE2). Kort sagt, detta gör det möjligt för en att läsa och skriva MS Excel-, MS Word- och MS PowerPoint-filer genom att använda Java-kod. De flesta Microsoft Office-filer – som XLS, DOC, PPT och MFC serialisering API-baserade filformat – är baserade på OLE2-standarden. OLE är i grunden en proprietär teknik utvecklad av Microsoft och tillhandahåller formatet för att länka objekt och bädda in objekt i containerdokument. Det första formatet kallas OLE1.0-format där det länkade objektet och den inbäddade objektdatan läggs ut som en sekvens av byte i behållardokumentet. Den andra versionen, OLE2.0-formatet, utnyttjar OLE Compound File Technology (MS-CFB) där det länkade objektet eller inbäddade objektdata finns i denna lagring i form av OLE Compound File Stream-objekt. Se formaten OLE1.0 och OLE2.0 för mer information om detta. Apache POI-bibliotek tillhandahåller biblioteks-API:er för OLE2-filsystemet som kallas POIFS och OLE2 Document Properties som kallas HPSF.
Apache POI-komponenter
Apache POI-biblioteket tillhandahåller klasser och metoder för att arbeta med OLE2-sammansatta dokument från MS Office. Här är en kort översikt över de mest använda:
- POIFS för OLE2-dokument:POIFS står för Poor Obfuscation Implementation File System . Detta är det grundläggande POI-elementet implementerat i biblioteket för att porta OLE2 Compound Document. Den stöder läs- och skrivfunktioner för det binära Microsoft Office-formatet som inte är XML. Alla API:er i POI-biblioteket bygger på detta.
- HSSF och XSSF:HSSF står för Horrible Spread Sheet Format . Det är en Java-implementeringsport för filformatet Excel 97 eller för .xls-filer. XSSF står för XML Spread Sheet Format och det är en port för filformatet OOXML eller .xlsx.
- HWPF och XWPF:HWPF står för Horrible Word Processor Format . Det är en begränsad skrivskyddad port för det äldre Word 6- eller Word 95-filformatet. XWPF står för XML Word Processor Format . Det är en Java-implementeringsport för Word 2007 .docx-filformatet. Båda implementeringarna stöder begränsad funktionalitet.
- HSLF och XSLF:HSLF står för Horrible Slide Layout Format . XSLF står för XML Slide Layout Format . Båda dessa ger möjlighet att läsa, skriva, skapa och ändra PowerPoint-presentationer medan HSLF stöder PowerPoint 97-formatet och XSLF stöder senare versioner.
- HPSF :HPSF står för Horrible Property Set Format . Den används särskilt för att arbeta med dokumentegenskaper som att ställa in titel, kategori, författare, datum för ändring och så vidare för ett dokument
- HDGF och XDGF:HDGF står för Horrible Diagram Format . Den här komponenten innehåller klasser för att arbeta med det binära filformatet Visio. Den tillhandahåller skrivskyddade API:er på låg nivå för åtkomst till Visio-dokument och VSD-filer. XDGF står för XML Diagram Format . Det är för Visio XML-filformatet eller VSDX-filer.
- HPBF :HPBF står för Horrible Publisher Format . Det är en begränsad Java-port för att fungera med filformatet MS Publisher.
Förkortningarna låter humoristiska eftersom dessa filsystem skulle vara stängda och Microsoft gjorde sitt bästa för att fördunkla koden så att de inte bara är svåra att förstå utan också svåra att bakåtkonstruera. Men utvecklarna på Apache hackade den med lätthet och reverse engineering den framgångsrikt. Kanske, som ett tecken på glädje eller fullständigt fördömande av slutet system, namngav de dem skämtsamt som sådana.
Arbeta med HSSF- och XSSF-filer
HSSF- och XSSF-komponenterna i Apache-biblioteket tillhandahåller tre modeller för åtkomst till ett kalkylbladsdokument enligt HSSF- och XSSF-dokumentationen. De är:
- Lågnivåstrukturer för särskilda behov
- Händelsemodellens API:er för skrivskyddad åtkomst till Excel-dokument
- Användarmodellens API:er för att skapa, läsa och ändra Excel-filer
API:erna för begränsade händelsemodeller kan endast användas för att läsa kalkylbladsdata. Dessa API:er finns i org.apache.poi.hssf.eventusermodel paket och org.apache.poi.xssf.eventusermodel paket, där det första används för att läsa data från .xls filformat och det andra används för att läsa data från .xlsx filformat.
Användarmodellen är mycket mer flexibel och enklare att använda; den kan läsa, skriva, skapa och ändra ett Excel-kalkylarksdokument. Men den har ett mycket högre minnesfotavtryck än händelsemodellen på låg nivå.
Att komma åt och manipulera det nyare OOXML-baserade filformatet med XSSF har också ett mycket högre minnesutrymme än de gamla HSSF-stödda binära filerna.
Från POI 3.5 och framåt har HSSF- och XSSF-modellen klubbats in i SS-modellen, ganska tweaked för att fungera för båda modellerna. Det är mer en justering av namn än en riktig förändring. På ett sätt kan vi säga att SS=HSSF+XSSF.
Migrera databastabelldata till ett Excel-kalkylblad
Här skapar vi ett enkelt verktygsprogram för att migrera vissa databasdata till ett Excel-ark. Detta kan också anpassas för att fungera med andra sätt, som att migrera Excel-data till en databastabell. Detta lämnas som en övning för läsaren. Programmet är enkelt och självförklarande. Besök Apache POI-dokumentation för detaljerad information om alla klasser eller metoder. För att prova följande exempel, vad vi har använt är följande:
- JDK 8
- MS Excel 2007
- Intellij IDEA IDE
- Apache POI 3.17
- Apache Derby 10.14
Besök lämpliga dokument och hjälpfiler för att ställa in projektet. Här är innehållet för filen Maven pom.xml som vi har använt.
<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>
Anteckning 1: pom.xml
En databastabell skapas med några dummyposter innan verktygsprogrammet körs. Här är koden för den filen.
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(); } }
Anteckning 2: DummyDatabase.java.
Det här är verktygsprogrammet vi pratar om. Koden skrevs i stor brådska och strukturen inte särskilt elegant. Det fungerar dock. Omstrukturera eller justera det som du tycker är lämpligt.
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()); } }
Anteckning 3: SSFile.java
Detta är kontrollpanelen från vilken verktygsprogrammet anropas.
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")); } }
Anteckning 4 :App.java
Innan du springer...
Se till att test1.xls eller test1.xlsx filer finns inte i d://temp katalogen innan programmet körs eftersom programmet varken skriver över eller kontrollerar filen med samma namn i katalogen där filen ska skapas. Se till detta varje gång programmet körs; annars ger koden ett otäckt felmeddelande. Du kan dock justera koden för att kontrollera.
Slutsats
Det finns ett annat alternativ till att arbeta med kalkylblad, som Apache POI-dokumentationen föreslår via Cocoon serializer, även om den fortfarande använder HSSF indirekt. Cocoon kan serialisera vilken XML-datakälla som helst genom att använda stilmallen och ange serializern. HSSF- och XSSF-modellen är ganska kraftfull och ger ett antal klasser och metoder för att hantera olika aspekter av ett Excel-dokument. Den här artikeln försökte ge en glimt av vad vi kan göra med Apache POI. Vi behöver ofta skriva ett verktygsprogram för att överbrygga mellan ett öppet och slutet system. Apache POI kan definitivt tjäna vårt syfte som en i sitt slag.
Referenser
- Apache POI – Java API för Microsoft Documents
- POI-HSSF och POI-XSSF – Java API för åtkomst till filer i Microsoft Excel-format