1 lutego 2011

Java - zapis i odczyt plików typu XLS

Dziś chciałbym przedstawić możliwości, jakie stwarza biblioteka Java Excel API. Biblioteka umożliwia generowanie arkuszy kalkulacyjnych popularnego środowiska Excel, który wchodzi w skład pakietu biurowego Microsoft Office. Wspomniana biblioteka obsługuje następujące pliki środowiska Excel: 95, 97, 2000, XP oraz 2003.

Na samym początku przedstawię w jaki sposób utworzyć plik typu XLS przy pomocy środowiska Java. W kolejnych krokach wypełnimy arkusz danymi, dokonamy formatowania oraz zastosujemy przykładową formułę. W końcowej części artykułu pokażę, w jaki sposób odczytać dane zawarte w arkuszu kalkulacyjnym. Przed przystąpieniem do pracy należy pobrać bibliotekę Java Excel API dostępną na stronie internetowej: http://jexcelapi.sourceforge.net/.

Zapis pliku XLS

W pierwszym kroku wypada zaimportować niezbędne pakiety:
import java.io.File;
import java.io.IOException;
import java.util.Calendar;
import java.util.Locale;
import jxl.write.*;
import jxl.write.Number;
import jxl.format.Colour;
import jxl.Workbook;
import jxl.WorkbookSettings;
Aby ułatwić zrozumienie programu, pozostała część kodu zostanie umieszczona w metodzie main() przy użyciu klauzuli throws z obsługą następujących wyjątków: IOException, WriteException.

public class ZapisXLS {
    public static void main(String[] args) throws IOException, WriteException {
        // … kod programu   
    }
}
W drugim kroku należy utworzyć plik skoroszytu, w którym zawarte zostaną spreparowane dane. Przy użyciu metody createSheet() utworzony zostanie pojedynczy arkusz kalkulacyjny, metoda przyjmuje dwa parametry. Pierwszy z nich określa nazwę arkusza, drugi parametr -  jego numer. Warto zaznaczyć, że arkusze numerowane są od zera. Dodatkowo korzystając z klasy WorkbookSettings ustawimy lokalizację arkusza.

WritableWorkbook skoroszyt = Workbook.createWorkbook(new File("przyklad.xls"));
WritableSheet arkusz = skoroszyt.createSheet("Arkusz", 0);
WorkbookSettings ustawienia = new WorkbookSettings();
ustawienia.setLocale(new Locale("pl", "PL"));
Przed wpisaniem nowych danych do arkusza skonfigurujmy przykładowy styl. Korzystając z klasy WritableFont i WritableCellFormat jesteśmy w stanie zdefiniować krój czcionki, rozmiar, kolor i tło.

WritableFont font = new WritableFont(WritableFont.TAHOMA, 12);
WritableCellFormat tahoma = new WritableCellFormat(font);
tahoma.setBackground(Colour.LIGHT_BLUE);
Nadszedł czas na wpisanie przykładowych wartości do arkusza. Przykładowe typy danych wspomnianej powyżej biblioteki przedstawiają się następująco:
- Label – etykieta, tekst,
- Numer – numer, liczba,
- DataTime – czas, godzina.

Wprowadzenie danych odbywa się przez utworzenie obiektu jednej z powyższych klas. Konstruktor obiektu w uogólnionej postaci przyjmuje następujące parametry: pierwszy z nich określa kolumnę, drugi wiersz, trzeci wartość, a czwarty parametr jest to obiekt klasy WritableCellFormat odpowiedzialny za sformatowanie tekstu. Warto wspomnieć, że numery kolumn i wierszy numerowane są od zera. Przy użyciu metody addCell() zapiszmy wartość do naszego arkusza.

Label tekst = new Label(1, 0, "Liczby", tahoma);
arkusz.addCell(tekst);
Korzystając z klasy Number wprowadźmy przykładowe wartości liczbowe do komórek arkusza kalkulacyjnego. Przy użyciu klasy WritableCellFormat oraz NumberFormats jesteśmy w stanie określić typ danych liczbowych. Przykładowe typy danych:
NumberFormats.FLOAT – liczba zmiennoprzecinkowa,
NumberFormats.INTEGER – liczba rzeczywista,
NumberFormats.TEXT – tekst.

Konstruktor obiektu w uogólnionej postaci przyjmuje następujące parametry: pierwszy z nich określa kolumnę, drugi wiersz, trzeci wartość, a czwarty parametr jest to obiekt klasy WritableCellFormat odpowiedzialny za sformatowanie tekstu. W tym przypadku również numer kolumny i wiersza numerowany jest od zera. Przy użyciu metody addCell() zapiszmy wartość do naszego arkusza.

WritableCellFormat format = new WritableCellFormat(NumberFormats.FLOAT);
Number number = new Number(1, 1, 5.1, format);
arkusz.addCell(number);
number = new Number(1, 2, 2.6754, format);
arkusz.addCell(number);
number = new Number(1, 3, 6.75, format);
arkusz.addCell(number);
Kolejnym przydatnym narzędziem jest klasa Formula, która umożliwia tworzenie formuł. Konstruktor obiektu w uogólnionej postaci przyjmuje następujące parametry: pierwszy z nich określa kolumnę, drugi wiersz, trzeci zapis formuły w formacie środowiska Excel, a czwarty parametr jest to obiekt klasy WritableCellFormat odpowiedzialny za sformatowanie tekstu. Wiersze i kolumny arkusza numerowane są od zera. Przy użyciu metody addCell() zapiszmy formułę do arkusza.

Formula formula = new Formula(1, 4, "SUM(B2:B4)", tahoma);
arkusz.addCell(formula);
Dodatkowo korzystając z obiektu klasy DataTime zapiszmy do komórki (1,6) aktualną datę, w identyczny sposób jak pozostałe typy danych – obiekty klas.

WritableCellFormat formatDaty = new WritableCellFormat(new DateFormat("dd-MM-yyyy"));
DateTime data = new DateTime(1, 6, Calendar.getInstance().getTime(), formatDaty);
arkusz.addCell(data);
Po zakończeniu pracy z arkuszem należy zapisać zmiany w skoroszycie oraz zamknąć plik. Dodatkowo wyświetlimy informację o zakończeniu procesu generowania dokumentu.

skoroszyt.write();
skoroszyt.close();
System.out.println("Dokument został wygenerowany.");
Poniższy rysunek przedstawia przykład wygenerowanego pliku XLS.


Odczyt z pliku XLS

Proces odczytu danych z pliku typu XLS zrealizujemy na podstawie utworzonego powyżej pliku arkusza kalkulacyjnego. Przed przystąpieniem do pracy należy zaimportować następujące pakiety:

import java.io.File;
import java.io.IOException;
import jxl.Cell;
import jxl.Sheet;
import jxl.read.biff.BiffException;
import jxl.Workbook;
Aby ułatwić zrozumienie programu, pozostała część kodu zostanie umieszczona w metodzie main() przy użyciu klauzuli throws z obsługą następujących wyjątków: IOException, BiffException.

public class OdczytXLS {
   public static void main(String[] args) throws IOException, BiffException {
   // … kod programu
   }
}
W pierwszym kroku otworzymy przykładowy plik XLS oraz przy pomocy metody getSheet() wskażemy numer arkusza. Warto zaznaczyć, że arkusze numerowane są od zera.

Workbook skoroszyt = Workbook.getWorkbook(new File("przyklad.xls"));
Sheet arkusz = skoroszyt.getSheet(0);
Korzystając z metody getCell() jesteśmy w stanie pobrać wartość odpowiedniej komórki arkusza. Metoda getCell() przyjmuje dwa argumenty: pierwszy określa kolumnę, drugi wiersz. Wartości kolumn i wierszy numerowane są od zera. Przy użyciu bezparametrowej metody getContents() dokonamy konwersji zwracanego typu danych do łańcucha tekstowego.

Cell komorka = arkusz.getCell(1, 0);
String naglowek = komorka.getContents();
System.out.println(naglowek);
Zatem w podobny sposób przy użyciu pętli programowej pobierzmy pozostałe dane i wyświetlmy je na ekranie.

 for(int i=1; i<4; i++){
     komorka = arkusz.getCell(1, i);
     System.out.println(komorka.getContents());
     }
   
Ostatnim krokiem jest zamknięcie pliku skoroszytu.

skoroszyt.close();
System.out.println("Odczyt zakończony sukcesem.");
Efekt działania programu przedstawia poniższy rysunek.

Biblioteka Java Excel API daje szerokie możliwości podczas procesu generowania i przetwarzania plików arkusza kalkulacyjnego. Zaprezentowana powyżej funkcjonalność stanowi zalążek możliwości jakie stwarza wykorzystana biblioteka, a jej zaawansowane możliwości pozwalają na swobodne tworzenie i przetwarzanie danych w dowolnie zaprojektowanym skoroszycie środowiska Microsoft Excel.

Na zakończenie powyższe przykłady: javaexcel.zip.
Nie ponoszę odpowiedzialności za błędy i następstwa powstałe wskutek działania programu i kodu. Pobierasz i użytkujesz na własną odpowiedzialność.