sql >> Databáze >  >> RDS >> Database

Jak vytvořit dokument Excel z programu Java pomocí Apache POI

POI Apache je populární knihovna s otevřeným zdrojovým kódem, která se používá ke čtení, zápisu a manipulaci se soubory MS Office a Open Office pomocí kódu Java. Knihovna je jedním z mnoha open source produktů spravovaných Apache Software Foundation (ASF) přispěla do komunity Java. Knihovna obsahuje třídy a metody pro dekódování formátů souborů založených na standardech Open Office XML a Microsoft OLE2. Ačkoli je knihovna schopna manipulovat se soubory Wordu, Excelu a PowerPointu, tento článek se zaměřuje hlavně na tabulkové dokumenty, jen aby byl stručný.

Naučte se JAVA a začněte bezplatnou zkušební verzi ještě dnes!

Knihovna POI Apache

Je zajímavé, že v názvu Apache POI, POI znamená „Poor Obfuscation Implementation“ a cílem knihovny je poskytovat Java API pro manipulaci s různými formáty souborů na základě standardů Office Open XML (OOXML) a formátu OLE 2 Compound Document společnosti Microsoft. (OLE2). Stručně řečeno, toto umožňuje číst a zapisovat soubory MS Excel, MS Word a MS PowerPoint pomocí kódu Java. Většina souborů Microsoft Office – jako jsou formáty souborů založené na serializačním API XLS, DOC, PPT a MFC – je založena na standardu OLE2. OLE je v podstatě proprietární technika vyvinutá od společnosti Microsoft a poskytuje formát pro spojování objektů a vkládání objektů do kontejnerových dokumentů. První formát se nazývá formát OLE1.0, kde jsou propojený objekt a data vloženého objektu uspořádána jako sekvence bajtů v dokumentu kontejneru. Druhá verze, formát OLE2.0, využívá technologii OLE Compound File Technology (MS-CFB), kde jsou data propojeného objektu nebo vloženého objektu obsažena v tomto úložišti ve formě objektů OLE Compound File Stream. Další podrobnosti naleznete v části Formáty OLE1.0 a OLE2.0. Knihovna POI Apache poskytuje rozhraní API knihovny pro souborový systém OLE2 s názvem POIFS a vlastnosti dokumentu OLE2 s názvem HPSF.

Apache POI Components

Knihovna Apache POI poskytuje třídy a metody pro práci s OLE2 složenými dokumenty MS Office. Zde je stručný přehled těch nejčastěji používaných:

  • POIFY pro dokumenty OLE2:POIFS znamená Systém souborů implementace špatného zmatku . Toto je základní prvek POI implementovaný v knihovně pro port OLE2 Compound Document. Podporuje funkce čtení a zápisu pro binární formát Microsoft Office, který není XML. Na tom jsou postavena všechna rozhraní API knihovny POI.
  • HSSF a XSSF:HSSF je zkratka pro Horrible Spread Sheet Format . Jedná se o implementační port Java pro souborový formát Excel 97 nebo pro soubory .xls. XSSF je zkratka pro XML Spread Sheet Format a je to port pro souborový formát OOXML nebo .xlsx.
  • HWPF a XWPF:HWPF je zkratka pro Hrozný formát textového procesoru . Jedná se o omezený port pouze pro čtení pro starší formát souborů Word 6 nebo Word 95. XWPF je zkratka pro XML Word Processor Format . Jedná se o implementační port Java pro formát souboru .docx aplikace Word 2007. Obě implementace podporují omezenou funkčnost.
  • HSLF a XSLF:HSLF znamená Hrozný formát rozvržení snímku . XSLF je zkratka pro Formát rozložení snímků XML . Oba umožňují čtení, zápis, vytváření a úpravy prezentací PowerPoint, zatímco HSLF podporuje formát PowerPoint 97 a XSLF podporuje novější verze.
  • HPSF :HPSF je zkratka pro Horrible Property Set Format . Používá se zejména pro práci s vlastnostmi dokumentu, jako je nastavení názvu, kategorie, autora, data úpravy a tak dále
  • HDGF a XDGF:HDGF je zkratka pro Horrible Diagram Format . Tato součást obsahuje třídy pro práci s binárním formátem souboru Visio. Poskytuje nízkoúrovňová rozhraní API pouze pro čtení pro přístup k dokumentům Visio a souborům VSD. XDGF znamená Formát diagramu XML . Je pro formát souboru Visio XML nebo soubory VSDX.
  • HPBF :HPBF znamená Hrozný formát vydavatele . Jedná se o omezený port Java pro práci se souborovým formátem MS Publisher.

Zkratky zní vtipně, protože tyto souborové systémy měly být zavřené a Microsoft se snažil kód zatemnit tak, aby byl nejen obtížně srozumitelný, ale také reverzní inženýrství. Vývojáři z Apache jej však snadno hackli a úspěšně reverzně zpracovali. Možná, že na znamení radosti nebo naprostého odsouzení uzavřeného systému je tak vtipně pojmenovali.

Práce se soubory HSSF a XSSF

Komponenty HSSF a XSSF knihovny Apache poskytují tři modely přístupu k tabulkovým dokumentům podle dokumentace HSSF a XSSF. Jsou to:

  • Nízkoúrovňové struktury pro speciální potřeby
  • Rozhraní API modelu událostí pro přístup pouze pro čtení k dokumentům aplikace Excel
  • Rozhraní API uživatelského modelu pro vytváření, čtení a úpravy souborů aplikace Excel

Omezená rozhraní API modelu událostí lze použít pouze pro čtení tabulkových dat. Tato rozhraní API jsou umístěna v org.apache.poi.hssf.eventusermodel balíček a org.apache.poi.xssf.eventusermodel balíček, kde první se používá ke čtení dat z .xls formát souboru a druhý se používá ke čtení dat z .xlsx formát souboru.

Uživatelský model je mnohem flexibilnější a snáze se používá; může číst, psát, vytvářet a upravovat tabulkový dokument aplikace Excel. Má však mnohem větší nároky na paměť než nízkoúrovňový model událostí.

Také přístup a manipulace s novějším formátem souborů založeným na OOXML pomocí XSSF má mnohem větší nároky na paměť než staré binární soubory s podporou HSSF.

Od POI 3.5 výše byly modely HSSF a XSSF začleněny do modelu SS, spíše vylepšeny, aby fungovaly pro oba modely. Jde spíše o úpravu jména než o skutečnou změnu. Svým způsobem můžeme říci, že SS=HSSF+XSSF.

Migrace dat databázové tabulky do tabulky Excel

Zde vytvoříme jednoduchý obslužný program pro migraci některých databázových dat do listu aplikace Excel. To lze také vyladit, aby fungovalo jinými způsoby, jako je migrace dat aplikace Excel do databázové tabulky. Toto je ponecháno jako cvičení pro čtenáře. Program je jednoduchý a srozumitelný. Podrobné informace o všech třídách nebo metodách naleznete v dokumentaci POI Apache. Pro vyzkoušení následujícího příkladu jsme použili následující:

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

Navštivte příslušné dokumenty a soubory nápovědy pro nastavení projektu. Zde je obsah souboru Maven pom.xml, který jsme použili.

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

Zápis 1: pom.xml

Před spuštěním obslužného programu se vytvoří databázová tabulka s několika fiktivními záznamy. Zde je kód tohoto souboru.

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();
   }
}

Zápis 2: DummyDatabase.java.

Toto je obslužný program, o kterém mluvíme. Kód byl napsán ve velkém spěchu a struktura nebyla příliš elegantní. Nicméně to funguje. Restrukturalizovat nebo upravit, jak uznáte za vhodné.

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());
   }
}

Zápis 3: SSFile.java

Toto je ovládací panel, ze kterého se obslužný program spouští.

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"));
   }
}

Výpis 4 :App.java

Před spuštěním…

Ujistěte se, že test1.xls nebo test1.xlsx soubory v d://temp neexistují adresář před spuštěním programu, protože program ani nepřepisuje ani nekontroluje soubor se stejným názvem v adresáři, kde má být soubor vytvořen. Ujistěte se o tom při každém spuštění programu; jinak kód zobrazí ošklivou chybovou zprávu. Můžete však kód vyladit, abyste provedli určitou kontrolu.

Závěr

Existuje další alternativa k práci s tabulkami, jak navrhuje dokumentace POI Apache prostřednictvím serializátoru Cocoon, i když stále nepřímo používá HSSF. Cocoon může serializovat jakýkoli zdroj dat XML použitím šablony stylů a určením serializátoru. Model HSSF a XSSF je poměrně výkonný a poskytuje řadu tříd a metod pro práci s různými aspekty dokumentu aplikace Excel. Tento článek se pokusil nastínit, co můžeme dělat s Apache POI. Často potřebujeme napsat obslužný program pro přemostění mezi otevřeným a uzavřeným systémem. Apache POI rozhodně může sloužit našemu účelu jako jediný svého druhu.

Odkazy

  • Apache POI – Java API pro Microsoft Documents
  • POI-HSSF a POI-XSSF – Java API pro přístup k souborům ve formátu Microsoft Excel

  1. Jak extrahovat den, měsíc a rok z data v SQLite

  2. Analýza dat ODBC v IBM SPSS

  3. Připojujete se k MS SQL Server s ověřováním Windows pomocí Pythonu?

  4. Mohu ukládat obrázky v MySQL