Controller im Glück

Von jeher gehört das Erstellen von Reports zu den Perl-typischen Aufgaben. Der spröde Charme der frühen ASCII-Berichte ist aber mittlerweile etwas in die Jahre gekommen, Excel ist viel beliebter. Mit dem passenden Perl-Modul sind Dateien in diesem Format leicht zu erzeugen.

In Pocket speichern vorlesen Druckansicht 9 Kommentare lesen
Lesezeit: 13 Min.
Von
  • Peter Dintelmann
  • Christian Kirsch
Inhaltsverzeichnis

Excels Stärke besteht darin, dass die Daten relativ einfach weiterzuverarbeiten sind, was die Beliebtheit dieses Dateiformats unter anderem bei Controllern erklärt. Mit dem Perl-Modul Spreadsheet::WriteExcel lassen sich auf recht einfache Weise Excel-Dateien auch auf Nicht-Windows-Systemen erstellen. Dazu sind vier Schritte erforderlich:

  • Erzeugung einer neuen Datei
  • Anlegen von Arbeitsmappen
  • Füllen und Formatieren der Zellen
  • Schließen der Datei

Die Hauptarbeit fällt naturgemäß im dritten Schritt an.

Bei dem von Spreadsheet::WriteExcel erzeugten Dateiformat handelt es sich um BIFF (Binary Interchange File Format). Es ist sowohl im Excel SDK als auch bei www.cubic.org/source/archive/fileform/misc/excel.txt beschrieben.

Nach dem Laden des Moduls erzeugt man eine neue Excel-Datei durch Aufruf des Konstruktors

use Spreadsheet::WriteExcel;
my $excel = new Spreadsheet::WriteExcel( "test.xls" );

Derzeit nimmt new() einen Dateinamen beziehungsweise ‘-’ für das Schreiben nach STDOUT entgegen. In der nächsten Version sind Handles aller Art verwendbar, wie in

my $excel = new Spreadsheet::WriteExcel( \*STDOUT );

um auf File- und Socket-Handles zu schreiben, beziehungsweise

my $excel = new Spreadsheet::WriteExcel( $fh );

für die objektorientierten Gegenstücke aus IO::Handle (insbesondere Instanzen von IO::File und IO::Socket). Nach Erzeugung der gesamten Excel-Datei sollte man diese schließen mit

$excel -> close();

Beim Erstellen von Excel-Daten aus einer Webanwendung bietet sich der Content-Type ‘application/vnd.ms-excel’ an. Derselbe MIME-Type dient zum Transport einer Excel-Datei (Base64-kodiert) innerhalb von E-Mail.

Im nächsten Schritt werden dem brandneuen Excel-Objekt einzelne Arbeitsmappen hinzugefügt:

my $sheet  = $excel -> addworksheet();
my $sheet2 = $excel -> addworksheet( "Titel" );

Verzichtet man auf den optionalen Titel, wählt Excel in der Darstellung einen Standard aus (zum Beispiel ‘Tabelle1’). Normalerweise ist in der Ansicht stets die erste Arbeitsmappe aktiv. Dies lässt sich durch die activate()-Methode ändern.

Für das Füllen von Arbeitsmappen mit Daten steht die Methode write() zur Verfügung.

$sheet -> write( $row, $column, $data, $format );

Ihr übergibt man neben der zu beschreibenden Zeile und Spalte (‘Zeilen zuerst, Spalten später’) den Inhalt sowie optional ein Formatobjekt. Auf Formate (dazu weiter unten mehr) verzichten die folgenden Zeilen

$sheet -> write( 0, 0, "Oben links" );
$sheet -> write( 0, 1, 7 );
$sheet -> write( 1, 1, 3 );
$sheet -> write( 2, 1, "=B1+B2" );
$sheet -> write( 4, 0, "http://www.heise.de/ix/" );

Formeln sind daran zu erkennen, dass sie mit einem Gleichheitszeichen beginnen, während das Modul alle mit ‘http://’ und ‘ftp://’ (in der nächsten Release auch ‘mailto:’) beginnenden Strings als URLs behandelt.

Hinter write() verbergen sich die fünf Methoden write_number(), write_string(), write_formula(), write_blank() und write_url(), die auch einzeln aufgerufen werden können. Die folgenden beiden Beispiele zeigen, wann dies sinnvoll sein kann.

$sheet -> write_string( 5, 0, "http://www.heise.de/ix/" );

schreibt die URL, ohne einen Link zu erzeugen, während

$sheet -> write_url( 6, 0,  "http://www.heise.de/ix/", "iX Startseite" );

den Link hinter einem vernünftigen Text verbirgt.

Bis jetzt ging es lediglich um das Schreiben von Daten in Zellen, wobei Excel das Standardlayout verwendet hat. Um dieses zu verändern, gibt es Formatobjekte, für die eine Vielzahl von Methoden bereitstehen. Ein solches Objekt erzeugt

$format = $excel -> addformat();

Dessen Methoden gehören zu den Kategorien Fonts und Farben, Zahlenformate, Muster, Ausrichtung (horizontal, vertikal) sowie Ränder. Die Unzahl der Zahlenformate soll hier außen vor bleiben.

Zum Einstellen der Schrift könnte man zum Beispiel

$format -> set_font( "Arial" );
$format -> set_size( 12 );
$format -> set_color( "red" );
$format -> set_bold();
$format -> set_underline();

einsetzen. Beschreibt man nun eine Zelle mit diesem Format

$sheet -> write( 2, 2, "Ich bin formatiert", $format );

so erscheint ihr Inhalt in 12 Punkt großer, fetter, unterstrichener Arial. Wie man am obigen Beispiel erkennt, kann das Erzeugen eines Formats in eine Vielzahl von Methodenaufrufen münden. Formate können kopiert werden, was erhebliche Schreibarbeit sparen kann:

$format2 = $sheet -> addformat();
$format2 -> copy( $format );
$format2 -> set_color( "green" );
$format2 -> set_italic();

$format2 repräsentiert nun eine 12 Punkt große, fette, unterstrichene, kursive Arial in Grün.

Ausschnitt aus der von Listing 1 erzeugten Farbtabelle (Abb. 1).

Farben lassen sich nicht nur als Text, sondern auch numerisch im Bereich 8 bis 63 spezifizieren. Einen Ausschnitt aus der Farbpalette zeigt Abbildung 1. Zur Veränderung der Hinter- oder Vordergrundfarbe eines Formats muss zunächst das zu verwendende Muster (aus 31 Möglichkeiten) mit set_pattern() gewählt werden. Der Wert 1 bedeutet dabei ein vollständiges Füllen der Zelle.

$format -> set_pattern( 1 );
$format -> set_fg_color( "silver" );

beschreibt eine Formatierung in solidem Silber als Vordergrund und

$format2 -> set_bg_color( "blue" );

dasselbe mit blauem Hintergrund (das Blau ist bei dem silbernen Vordergrund allerdings nicht erkennbar).

Mehr Infos

Listing 1

Das Skript erzeugt eine Excel-Datei mit vier Arbeitsmappen: Je eine für Schriften, Farben, Füllmuster und Textausrichtung. Es basiert auf Material des Modulentwicklers John McNamara.

#!/usr/bin/perl

use strict;
use Spreadsheet::WriteExcel;

# ----- Exceldatei anlegen -----
#
my $excel = new Spreadsheet::WriteExcel( "test.xls" );

# ----- Formate -----
#
my $center = $excel -> addformat();
my $head = $excel -> addformat();

$center -> set_align( "center" );
$head -> set_align( "center" );
$head -> set_bold();

# ----- Unterroutinen aufrufen -----
# * Jede Unterroutine erzeugt eine eigene Excel-Arbeitsmappe.
#
fonts(); # Mappe 'Fonts'
farben(); # Mappe 'Farben'
muster(); # Mappe 'Muster'
align(); # Mappe 'Ausrichtung'

# ----- Ausgabe beenden -----
#
$excel -> close();

# ----- fonts() -----
# * Darstellung einiger ausgewählter Fonts.
#
sub fonts {
my $sheet = $excel -> addworksheet( "Fonts" );

$sheet -> set_column( 0, 0, 30 );
$sheet -> set_column( 1, 1, 10 );

$sheet -> write( 0, 0, "Font", $head );
$sheet -> write( 0, 1, "Größe", $head );

my @fonts = ( [ 10, "Arial" ],
[ 12, "Arial" ],
[ 14, "Arial" ],
[ 12, "Arial Black" ],
[ 12, "Arial Narrow" ],
[ 12, "Century Schoolbook" ],
[ 12, "Courier" ],
[ 12, "Courier New" ],
[ 12, "Garamond" ],
[ 12, "Impact" ],
[ 12, "Lucida Handwriting" ],
[ 12, "Times New Roman" ],
[ 12, "Symbol" ],
[ 12, "Wingdings" ],
[ 12, "Ein nichtexistenter Font" ],
);

for (my $i=0; $i<=$#fonts; $i++) {
my $format = $excel -> addformat();
$format -> set_size( @fonts->[$i]->[0] );
$format -> set_font( @fonts->[$i]->[1] );

$sheet -> write( $i+1, 0, @fonts->[$i]->[1], $format );
$sheet -> write( $i+1, 1, @fonts->[$i]->[0], $format );
}
}

# ----- farben() -----
# * Erzeugung der Farbtafeln auf Namens- und Indexbasis.
#
sub farben {
my $sheet = $excel -> addworksheet( "Farben" );

$sheet -> write( 0, 0, "Name", $head );
$sheet -> write( 0, 1, "Farbe", $head );
$sheet -> write( 0, 3, "Index", $head );
$sheet -> write( 0, 4, "Farbe", $head );

my @colors = qw( aqua black blü fuchsia gray green lime
navy orange purple red silver white yellow
);

foreach (0..$#colors) {
my $format = $excel -> addformat();

$format -> set_color( $colors[$_] );
$format -> set_align( "center" );
$format -> set_bold();

$sheet -> write( $_+1, 0, $colors[$_], $center );
$sheet -> write( $_+1, 1, $colors[$_], $format );
}

foreach (8..63) {
my $format = $excel -> addformat();

$format -> set_color( $_ );
$format -> set_align( "center" );
$format -> set_bold();

$sheet -> write( $_-7, 3, $_, $center );
$sheet -> write( $_-7, 4, "Farbe", $format );
}
}

# ----- muster() -----
# * Darstellung der möglichen Muster mit grünem Vorder-
# und silbrigem Hintergrund.
#
sub muster {
...
}

# ----- align() -----
# * Vertikale und horizontale Ausrichtung von Zelleninhalten.
# * Darstellung gedrehter Schrift.
#
sub align
{ ...
}

Zur Einstellung der Breite von Spaltenbereichen und von Zeilen gibt es zwei Methoden:

$sheet -> set_column( $firstCol, $lastCol, $width, $format );
$sheet -> set_row( $row, $height, $format );

Dabei ist das Formatargument optional und kommt nur beim anschließenden Öffnen der Datei in Excel zum Zuge: Es bestimmt das Aussehen aller danach in dem angegebenen Bereich interaktiv eingegebenen Daten, nicht jedoch das von Zellen, die man mit $sheet->write() füllt.

Meist wird man daher auf diesen Parameter verzichten. Um nur das Format einzustellen, die Höhe beziehungsweise Breite aber beizubehalten, setzt man den Wert für die Abmessung auf undef. Zur Ausrichtung der Zelleninhalte dient die Methode set_align():

$format -> set_align( "right" );
$format -> set_align( "vcenter" );

führt zum Beispiel zu einer rechtsbündigen, vertikal zentrierten Ausrichtung des Inhalts in der Zelle. Wem dies nicht reicht, der kann die Schrift noch drehen. Um vertikal von oben nach unten zu schreiben, benutzt man

$format -> set_rotation( 1 );

Mit set_border() und set_border_color() lassen sich die Zellenränder festlegen.

Eine beliebte Anwendung für Excel-Tabellen sind Reisekostenabrechnungen: Den nötigen Aufwand vorausgesetzt, lässt sich mit Makros und VisualBasic-Funktionen sicherstellen, dass die Mitarbeiter beim Ausfüllen keine Fehler machen. Die jeweils anzuwendenden Pauschalsätze für Übernachtungen und Verpflegung kann der Controller in einem eigenen Arbeitsblatt bequem pflegen. Hätte jede Reisende Excel, wären Reisekostenabrechnungen kein Grund zur Sorge mehr.

Zumindest in manchen Betrieben gibt es aber Excel-lose Zeitgenossen. Für die bietet sich eher eine Weblösung zum Ausfüllen des Formulars an - ebenso wie für alle anderen, die regelmäßig vergessen, sich die aktuelle Fassung der Arbeitsmappe vom Firmenserver zu laden.

Auszüge aus einer recht simplen Lösung per Perl-CGI-Skript zeigt Listing 2. Sie benutzt neben Spreadsheet::WriteExcel die Module CGI und Date::Calc, wie immer auf dem CPAN (www.cpan.org) zu finden. Das Skript besteht im Wesentlichen aus zwei Routinen, write_form und write_sheet.

Mehr Infos

Listing 2

Auszüge aus der Reisekostenabrechnung per Webformular.

#!/usr/local/bin/perl

use CGI::Pretty qw/:standard :html3 :cgi-lib -no_xhtml -oldstyle_urls/;
use strict;
use Spreadsheet::WriteExcel;
use Date::Calc qw(Date_to_Days Delta_Days);

use vars qw ($sheet $zeile $text_f);

my $sheetbase = "/tmp/rk_";
my $ueber_pausch = "39"; # Pauschale für Übernachtungskosten
my $kuerzung_frueh = "9" ; # Kürzung für Frühstück im Hotelpreis
my $km_pausch = "0.52"; # Kilometerpauschale
my %pausch = ( "8" => "10",
"14" => "20",
"24" => "46");
my @pausch_sprung = sort { $a <=> $b } keys %pausch;

my $q = new CGI;

if ( $q->param()) {
write_sheet();
} else {
write_form();
}

sub write_form {

my @table;

...

push @table, TR(td({colspan => 2},b("Übernachtungskosten")));
autoEscape(undef);
push @table, TR(td([radio_group(-name => "hotel",
-rows => 2,
-default => 'Einzelnachweis',
-values => [
'Einzelnachweis',
'Pauschal' ,
]
),
textfield(-name => "hotel_einzeln",
-size => 20,
-maxlength => 100) . " " .
checkbox(-name => "hotel_fruehstuck",
-label => " Inkl. Frühstück",
-checked => 0,
-value => "1")]));
...
autoEscape(1);
...

print header, start_html(-title => "Reisekosten Inland",
-bgcolor => "#CCCCCC"),
start_form(-name => "RKForm",
-method => "GET"),
table(@table);

print submit(-name => "Abschicken"),end_form, end_html;

}

sub zeit {
my ($name) = @_;
return popup_menu(-name => $name . "stunde",
-values => [ '0' .. '23']) . b(":") .
popup_menu(-name => $name . "minute",
-values => ['00' , '15', '30', '45']);
}

sub write_sheet {
my $filename = $sheetbase . param("nname") .".xls";
my $excel = new Spreadsheet::WriteExcel($filename);

$text_f = $excel->addformat();
my $head1_f = $excel->addformat();
my $head2_f = $excel->addformat();
my $date_f = $excel->addformat();
my $time_f = $excel->addformat();
my $money_f = $excel->addformat();
my $times_f = $excel->addformat();
my (@fahrt, @verpflegung, @uebernachtung);

...
$head2_f->set_bold();
$head2_f->set_font("Arial");
$head2_f->set_size("10");

$text_f->copy($head2_f);
$text_f->set_bold(0);

$date_f->copy($text_f);
$date_f->set_num_format('dd.mm.yyyy');
...

$sheet = $excel->addworksheet();
$zeile = 0;
$sheet->write($zeile,0,"Reisekostenabrechnung",$head1_f);
$zeile = 2;
beschriftung("Vorname, Nachname:" .
param("vname"). " ".param("nname"));
$zeile++;
beschriftung("Abteilung: iX-Redaktion");
$zeile += 2;
beschriftung("Reisebeginn am");
$sheet->write($zeile,1,excel_date("beginn"),$date_f);
$sheet->write($zeile,2,excel_time("beginn"),$time_f);
$zeile++;
...
$sheet->write($zeile,0,"Kilometergeld:",$text_f);
if (param("pkw")) {
$sheet->write($zeile,1,param("pkw"),$times_f);
$sheet->write($zeile,2,$km_pausch,$money_f);
$sheet->write_formula($zeile,3,
"=".rowcol_to_cell($zeile,1)."*$km_pausch",
$money_f);
}

...
$sheet->write($zeile,0,"Verpflegungspauschale",$head2_f);
$sheet->write($zeile,1,"Anzahl Tage",$text_f);
$sheet->write($zeile,2,"Pauschale",$text_f);
$zeile++;
$verpflegung[0] = $zeile;

my $count;
foreach my $h (@pausch_sprung) {
if ($h == 24) {
$count = tage_gesamt() - 1;
beschriftung("Täglich für 24 Std.");
} else {
$count = (erster_tag() == $h ? 1:0) +
(letzter_tag() == $h ? 1: 0);
beschriftung("Täglich über $h Std.");

}
if ($count) {
$sheet->write($zeile,1,$count,$times_f);
$sheet->write($zeile,2,$pausch{$h},$money_f);
$sheet->write($zeile,3,"=".rowcol_to_cell($zeile,1).
"*".rowcol_to_cell($zeile,2),$money_f);
}
$zeile++;
}

...
$zeile += 3;
beschriftung("Auszahlung(+)/Rückzahlung(-)");
$sheet->write($zeile,3,"=" .
rowcol_to_cell($zeile-2,3). "-" .
rowcol_to_cell($zeile-1,3),$money_f);
$excel->close();

}
sub beschriftung {
$sheet->write($zeile,0,$_[0],$text_f);
}

sub excel_date{
my ($prefix) = @_;
my $string = "=DATE(" .
join(',',((param($prefix."jahr") || 2000) - 1900,
param($prefix."monat") || 1,
param($prefix."tag") || 1)) . ")";
return $string;
}

sub tage_gesamt {
return Delta_Days(param("beginnjahr"), param("beginnmonat"),
param("beginntag"),
param("endejahr"), param("endemonat"),
param("endetag"));
}

sub erster_tag {
my $minutes;
if (tage_gesamt) {
$minutes = (24 - param("beginnstunde")) * 60 - param("beginnminute");
} else {
$minutes = param("beginnstunde") * 60 + param("beginnminute");
}
foreach my $p (reverse @pausch_sprung) {
return $p if ($minutes >= $p * 60);
}
return 0;
}

Ruft ein Anwender das Skript zum ersten Mal auf, gibt $q->param() nichts zurück (da ja noch keine CGI-Parameter vorhanden sind), und write_form() erzeugt das Formular. Das ist mit dem CGI-Modul schnell erledigt und nicht weiter spektakulär. Das Formular besteht vor allem aus einer großen Tabelle @table, in deren ersten Spalte die Beschriftungen für die Eingabefelder der zweiten Spalte stehen (siehe Abbildung 2). Die einzelnen Zeilen schreibt push() nacheinander in @table.

Im HTML-Formular für die Reisekostenabrechnung kann man Formeln ebenso wie in Excel eingeben, um sich das Zusammenrechnen zu sparen (Abb. 2).

Beispielhaft herausgegriffen seien die Skriptzeilen zum Erzeugen der Felder für die Übernachtungskosten (siehe Listing 2). Sie erzeugen zunächst die Überschrift, die sich über zwei Spalten erstrecken soll (colspan => 2). In die nächste Tabellenzeile kommt erst eine Radiobox, mit der die Anwenderin einstellt, ob sie die Reisekosten pauschal oder per Einzelnachweis abrechnet. Rechts daneben steht das Feld ‘hotel_einzeln’ zum Eingeben des Betrages. Ihm folgt eine Checkbox, die anzuklicken ist, wenn Frühstück im Preis enthalten war: In diesem Fall muss der Arbeitgeber die Hotelkosten um einen Pauschalbetrag kürzen. Radiobox, Eingabefeld und Checkbox sind Elemente eines Array, das als Parameter an die CGI-Funktion td() übergeben wird. Sie verpackt jedes Array-Element in ein TD-Element. Der Aufruf von TR schließlich generiert die TR-Tags, die die Tabellenzeile einschließen. Wichtig ist hier die Großschreibung, da tr ein Perl-Operator ist.

Wenn alle Formularzeilen erzeugt sind, gibt write_form den HTML-Header aus, gefolgt von der Tabelle und einem submit-Knopf innerhalb eines FORM-Elements. Eine echte Applikation sollte zusätzlich Code zur Fehlerprüfung enthalten. Das lässt sich beispielsweise mit JavaScript erledigen, falls die Firmenpolitik dessen Einsatz gestattet.

Hat der Dienstreisende das Formular ausgefüllt und abgeschickt, liefert der Aufruf von $q->param die Anzahl der übergebenen CGI-Parameter. Da die größer als null ist, ruft das Skript die Routine write_sheet() auf, um das Excel-Blatt zu erstellen. Sie definiert zunächst einige Formate: $text_f für normalen Text, $head1_f und $head2_f für Überschriften, $date_f und $time_f für Daten und Zeiten, $money_f für Währungsbeträge sowie $times_f für Zahlen gefolgt von einem Malzeichen (x). Während die ersten drei nur einfache Textattribute einstellen, verwenden die übrigen Formate die Methode set_num_format(), um festzulegen, wie Excel die Werte darstellen soll. So sorgt $date_f->set_num_format("dd.mm.yyyy") dafür, dass mit $date_f formatierte Werte das hierzulande übliche Datum zeigen.

Das eigentliche Schreiben der Excel-Tabelle erfordert keine ausführlichen Erläuterungen. Per param() erfolgt der Zugriff auf die Daten des HTML-Formulars, param("vname") liefert beispielsweise den Vornamen des Reisenden. Fast immer reicht das Skript diese Parameter ohne nähere Betrachtung weiter an die write()-Methode des Excel-Moduls. Dadurch können Benutzer etwa im Feld ‘Bahnkosten’ des Formulars ‘=150+33+6+201’ eingeben - das Zusammenrechnen erledigt Excel.

Viele andere Berechnungen bleiben Excel ebenfalls überlassen. So übernimmt es das Ermitteln der Übernachtungspauschale:

$sheet->write($zeile,1,tage_gesamt(),$times_f);
$sheet->write($zeile,2,$ueber_pausch, $money_f);
$sheet->write($zeile,3,"=".rowcol_to_cell($zeile,1).
"*".rowcol_to_cell($zeile,2),$money_f);

tage_gesamt() ist eine Perl-Funktion, die mit Hilfe des Date::Calc-Moduls die Reisedauer in Tagen liefert. Das letzte Statement schließlich schreibt die Formel, die die Tage mit dem Pauschalsatz multipliziert. Da Excel-Formeln Zellen als ‘A1’, ‘B2’ und so weiter ansprechen, muss ein Aufruf von rowcol_to_cell() die nötige Konvertierung von der numerischen Zeilen/Spalten-Adressierung erledigen.

Was sie per Excel- und was per Perl-Funktion erledigen möchte, bleibt letztlich jeder selbst überlassen. Im Beispiel berechnet Excel alles, was sich mit seinen Mitteln leicht hinbekommen lässt: Multiplikationen, Additionen et cetera. Wenn es kniffliger wird, etwa bei der Ermittlung der Details für die Verpflegungskosten, muss Perl ran. Der Pauschalbetrag für diese hängt von der Reisedauer ab: für 8, 14 und 24 Stunden gibt es jeweils unterschiedliche Werte. Im Listing liefern die Funktionen erster_tag() und letzter_tag() den passenden Wert (0, 8, 14 oder 24) zurück,

$count = (erster_tag() == $_ ? 1:0) + (letzter_tag() == $_ ? 1: 0);

ermittelt, ob 0, 1, oder 2 Tage mit acht beziehungsweise vierzehn Stunden anzusetzen sind. Das ließe sich auch mit Excel-Funktionen berechnen, erforderte allerdings deutlich mehr Aufwand. Zudem sind Stundensprünge samt dazugehörigen Pauschalsätzen in einem Hash (%pausch_sprung) abgelegt: Ändern sich die Vorschriften, reicht eine Anpassung an dieser zentralen Stelle.

Für den täglichen harten Einsatz eignet sich die vorgestellte Anwendung sicher nicht. Dafür fehlt mindestens die Fehlerprüfung: Noch sind Reisen mit negativer Dauer in unserem Teil des Universums nicht möglich, und fehlerhafte Eingaben sollte das Formular verhindern. Zudem sind zu viele Dinge hart in den einzelnen write()-Aufrufen kodiert. Als Alternative dazu bietet sich ähnlich wie beim Erzeugen des HTML-Formulars ein Array an, das man in einer knappen Schleife ausgibt.

Formeln und Funktionen gehören zu den Teilen des Moduls, die noch nicht vollständig implementiert sind. Dies ist angesichts der aktuellen Versionsnummer 0.3 nicht weiter verwunderlich. In diesem Bereich soll es in den nächsten Versionen große Fortschritte geben. Vieles funktioniert jedoch schon, wie das Reisekostenexperiment zeigt: =TIME(10,15,0) ebenso wie =SUM(C22:C40). Noch sind alle Funktionsnamen auf Englisch anzugeben, aber der Entwickler John McNamara arbeitet daran, anderssprachige Bezeichnungen zu ermöglichen. Die mitgelieferte Dokumentation sowie Beispiele geben über den jeweiligen Stand Aufschluss. Die nächste Version soll unter anderem Möglichkeiten zur Gestaltung der Kopf- und Fußzeilen sowie der Seitenränder und -größe enthalten. Für die Zukunft ist ferner eine Umstellung des Dateiformats auf Excel 97/2000 geplant.

Dr. Peter Dintelmann
ist gelernter Mathematiker und für die Dresdner Bank im Bereich Transaction Banking, Market Information Services, tätig.

[1] John McNamara; Spreadsheet::WriteExcel; The Perl Journal Vol. 5 No. 3, S. 22

Mehr Infos

iX-TRACT

  • Das Perl-Modul Spreadsheet: WriteExcel erzeugt auf beliebigen Plattformen Excel-Dateien.
  • Zahlreiche Methoden ermöglichen das Formatieren der Zellinhalte.
  • Noch sind nicht alle Excel-Funktionen und -Formeln von Perl aus benutzbar.
Mehr Infos

Installation

Spreadsheet::WriteExcel benötigt als Voraussetzung das Modul Parse::RecDescent. Beide sind in den bekannten vier Schritten zu installieren, was für das Excel-Modul wie folgt aussieht:

gzip -dc Spreadsheet-WriteExcel.tar.gz | tar xf -
cd Spreadsheet-WriteExcel
perl Makefile.PL
make
make test && make install

Die Perl-Module sind wie üblich über das CPAN (Comprehensive Perl Archive Network, www.cpan.org) erhältlich. Spreadsheet::WriteExcel ist vollständig in Perl geschrieben, sodass zur Installation kein Compiler nötig ist.

Benutzer des unter Windows verbreiteten ActivePerl können zur Installation über das Internet den PPM (Perl Package Manager) einsetzen:

set HTTP_proxy=http://myproxy.far.away:8080
ppm
PPM> set repository tmp http://homepage.eircom.net/~jmcnamara/perl
PPM> install Spreadsheet-WriteExcel
PPM> quit

Die Umgebungsvariable HTTP_proxy ist nur bei Verwendung eines HTTP-Proxy-Servers erforderlich.

(ck)