inhoudstafel en auteursrecht
* STER *


9. Interactie tussen MS Excel en Java

9.1 De gesloten wereld van Microsoft

Java is sinds enige tijd de aangewezen oplossing voor het ontsluiten van bedrijfsinformatie. Daardoor groeit de behoefte, Java-programma's te laten interageren (lezen en schrijven) met bestanden in het eigen formaat van kantoortoepassingen, in het bijzonder met spreadsheets (rekenbladen).

Microsoft Corporation (MS) is momenteel de marktleider inzake kantoortoepassingen met zijn kantoorsuite MS Office. Vooral het spreadsheetprogramma Excel zal het nog wel enige jaartjes uitzingen aan de top. Jammer genoeg ontmoedigt MS alle interactie met de buitenwereld: de bestandsformaten van MS Office zijn ingewikkeld, veranderlijk, onefficiënt en - wat het ergste is - grotendeels ongedocumenteerd.

Een groep Open Source-ontwikkelaars heeft de uitdaging aangenomen. Het project POI (http://jakarta.apache.org/poi/), onderdeel van de Jakarta-familie (http://jakarta.apache.org), heeft tot doel de bestandformaten van MS Office toegankelijk te maken voor Java-programmeurs. POI is onderverdeeld in (voorlopig) de volgende deelprojecten:

De volgende paragrafen van dit hoofdstuk gaan over het eenvoudige gebruik van HSSF. HSSF dient om Excel-bestanden te lezen, te wijzigen en te creëren. De afkorting HSSF staat voor horrible spreadsheet format ("vreselijk rekenbladformaat"), een verwijzing naar de complexe interne vorm die Excel-bestanden aannemen.

Om POI te programmeren heb je klassen nodig buiten de gewone Java Development Kit. Je kan ze downloaden vanaf de POI-website (zie hierboven). Wij hebben gekozen voor de binaire versie poi-bin-2.5.1-final-20040804.zip. Maar omdat POI een Open Source-project is, kan je natuurlijk ook de broncode downloaden en zelf compileren. In het ZIP-archief vinden we de documentatie (ondermeer de API-documentatie in Javadoc-formaat) en een JAR-bestand poi-2.5.1-final-20040804.jar; dat laatste moeten we opnemen in het classpath, zowel bij het compileren als bij het uitvoeren van onze voorbeeldprogramma's.

9.2 Het gebruikersmodel van HSSF

De volledige HSSF application programming interface (API) laat interactie toe op verscheidenen technische niveaus. We beperken ons in deze tekst tot het hoogste (meest abstracte, dus meest eenvoudige) niveau, het user model. In het user model wordt een spreadsheet aangesproken in termen van de objecten waarmee Excel-gebruikers vertrouwd zijn: rekenboek (workbook), rekenblad (worksheet), cel, enz. De tabel hieronder geeft de namen van de klassen in het pakket net.sourceforge.poi.hssf.usermodel die de vertrouwde Excel-onderdelen implementeren.

Excel-object Java-klasse
rekenboek HSSFWorkbook
rekenblad HSSFSheet
rij HSSFRow
kolom -
cel HSSFCell

Er is geen specifieke klasse die een kolom modelleert. Een cel uit een gegeven kolomnummer moet je adresseren via de rij waarin ze voorkomt, met methoden die het kolomnummer als argument accepteren.

9.3 Een werkboek aanmaken

De klasse HSSFWorkbook heeft een constructor zonder parameter die een nieuw werkboek opbouwt in het geheugen van de virtuele machine. Aanvankelijk is het werkboek leeg, dus zonder werkbladen (in tegenstelling tot een "nieuw werkboek" in Excel, dat begint met drie lege werkbladen).

Met de methode

  write(OutputStream stream)

kan de inhoud van het werkboek worden weggeschreven naar een bestand in de vorm van een FileOutputStream (zie paragraaf 4b.3).

De methode createSheet(String sheetname) maakt een nieuw werkblad (een object van de klasse HSSFSheet) en voegt het toe aan het bewuste werkboek. Je kunt achteraf de naam van het werkblad nog wijzigen met de methode setSheetName(int sheet, String name). In dat geval bepaalt de parameter sheet over welk werkblad het gaat (nummering vanaf 0).

De klasse HSSFSheet bevat op haar beurt een methode createRow(int rownum) om een rij toe te voegen aan het rekenblad. In den beginne heeft het rekenblad dus geen rijen, zelfs geen lege! Die nieuwe rij, van het type HSSFRow, is trouwens zelf ook leeg; met haar methode createCell(short column) maak je een cell op de gegeven plaats in de rij. De kolomindex column telt vanaf 0, dus bijvoorbeeld de E-kolom heeft index 4.

Het type van een cell is in principe een van de volgende zes mogelijkheden, telkens weergegeven door een symbolische constante (een static final int attribuut van de klasse HSSFCell).

Celtype Symbolische Constante Numerieke Waarde
leeg CELL_TYPE_BLANK 3
logische waarde CELL_TYPE_BOOLEAN 4
fout CELL_TYPE_ERROR 5
formule CELL_TYPE_FORMULA 2
getal of datum CELL_TYPE_NUMERIC 0
tekst CELL_TYPE_STRING 1

Je kan het celtype expliciet instellen door een aanroep van de methode setCellType(int cellType). Let op: de huidige versie van het HSSF-project laat alleen getallen (eventueel datums) en teksten toe - geen formules! Het celtype wordt echter vanzelf correct ingesteld door elk van de vier versies van de methode setCellValue, waarmee je de inhoud van de cel kunt instellen of wijzigen:

  public void setCellValue(Calendar value) // numeriek
  public void setCellValue(Date value)     // numeriek
  public void setCellValue(double value)   // numeriek
  public void setCellValue(String value)   // tekst

Voorbeeld

Het volgende voorbeeldprogramma maakt een werkboek met één werkblad. De eerste kolom bevat de getallen van 1 tot 10, de tweede kolom hun kwadraten.

import java.io.*;
import org.apache.poi.hssf.usermodel.*;

/** Voorbeeldprogramma ter illustratie van het
 *  aanmaken van Excel-bestanden.
 */
public class HelloExcel {
  /** Maak een demonstratiebestand met twee kolommen getallen.
   *  @param args[0]
   *    Naam of padnaam van het aan te maken bestand.
   */
  public static void main(String[] args)
    throws IOException {
    FileOutputStream bestand =
      new FileOutputStream(args[0]);
    HSSFWorkbook werkboek = new HSSFWorkbook();
    HSSFSheet werkblad = werkboek.createSheet("mijn werkblad");
    for (short rownum = (short) 0; rownum < 10; rownum++) {
      HSSFRow rij = werkblad.createRow(rownum);
      HSSFCell cel = rij.createCell((short) 0);
      cel.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
      cel.setCellValue(rownum + 1);
      cel = rij.createCell((short) 1);
      cel.setCellType(HSSFCell.CELL_TYPE_NUMERIC);
      cel.setCellValue((rownum + 1) * (rownum + 1));
    }
    werkboek.write(bestand);
    bestand.close();
  }
}

Met de opdracht

  werkboek.write(bestand);

schrijven we de inhoud van het werkboek, die zich tot dan toe slechts in het geheugen van de virtuele machine bevond, naar een bestand op de harde schijf. De (pad)naam van het bestand geven we mee als argument in de opdrachtregel.

Voor we het programma uit kunnen voeren, moeten we het kunnen compileren. De opdrachtregel voor het compileren moet verwijzen naar het archiefbestand (jarfile) waar we het pakket org.apache.poi.hssf.usermodel kunnen vinden. De precieze plaats van dat bestand hangt af van de manier waarop we POI hebben geïnstalleerd op onze machine. Bij ons is het

  javac -classpath c:\dev\poi\poi-2.5.1-final-20040804.jar HelloExcel.java

Bij het uitvoeren van het programma moeten we in het classpath niet alleen bovengenoemde jarfile opnemen, maar ook de huidige directory (aangegeven door een punt). Start het programma door te typen

  java -cp c:\dev\poi\poi-2.5.1-final-20040804.jar;. HelloExcel kwadraten.xls

Nu maakt het programma een Excel-bestand met de naam kwadraten.xls in de huidige map. Als er zo al een bestand in de map stond, dan wist het programma zijn vorige inhoud uit. De extensie .xls is technisch niet noodzakelijk, maar maakt één en ander wel herkenbaarder. Bovendien kan je dan, door (een icoon van) het bestand te dubbelklikken met de muis, MS Excel opstarten - als dat programma op je computer aanwezig is. Overigens werkt ons voorbeeldprogramma in eender welke Java-omgeving, onafhankelijk van enig Microsoft-programma. Om de inhoud van het gecreëerde werkboek te inspecteren, heb je wel Excel nodig (of een Java-programma zoals in de volgende paragraaf).

1 1 2 4 3 9 4 16 5 25 6 36 7 49 8 64 9 81 10 100
figuur: Uitzicht van het bestand kwadraten.xls in Excel

9.4 Een werkboek lezen

in voorbereiding

9.5 Een werkboek wijzigen

in voorbereiding


inhoudstafel en auteursrecht
* STER *

Valid HTML 4.0! Valid CSS!