Programowanie Perl rep


Raportowanie w Perlu
PROGRAMOWANIE
Profesjonalne raportowanie w Perlu
Zróbmy to w Excelu
Stare powiedzenie, szczególnie po-
matów? Otóż przemawia za tym kilka powo- moduł dostarcza interfejsów do maksymalnie
dów. Po pierwsze jest to format przenośny, dużej liczby właściwości Excela. Rzeczywiście
pularne w gronie użytkowników
z którym bez większych problemów radzą so- mnogość metod modułu opisanych w doku-
Perla mówi, że wszystko można zro- bie aplikacje linuksowe. Wymienię najważ- mentacji z początku może trochę onieśmielać,
niejsze: Gnumeric, OpenOffice i StarOffice, ale nie należy się tym zrażać. Zastosowanie ich
bić na wiele sposobów. Zależy to
KOffice. Jest więc w czym wybierać. Efekt jest bardzo intuicyjne i nawet osoby niezazna-
przenośności możemy spotęgować, tworząc jomione z podejściem obiektowym nie powin-
nie tylko od umiejętności i przyzwy-
np. własną aplikację raportującą z interfejsem ny mieć większych problemów i będą w stanie
czajeń programisty, ale czasami też WWW, czerpiącą dane wprost z korporacyjnej szybko pisać własne raporty.
bazy danych. Co więcej, sporządzając raport Żeby to udowodnić, zacznijmy w sposób tra-
od potrzeb i przyzwyczajeń odbiorcy
w tym formacie, umożliwiamy użytkownikom dycyjny od napisania najprostszego raportu,
dokonywanie własnych przeliczeń, sortowanie który de facto niczego nie raportuje, ale pozwa-
 użytkownika programu.
i tym podobne operacje, właściwe dla arkuszy la zapoznać się ze sposobem korzystania z mo-
WOJCIECH BOLIMOWSKI kalkulacyjnych. dułu (Listing 1). W pierwszym kroku deklaru-
jemy wykorzystanie modułu. Następnie dekla-
Koń roboczy  moduł rujemy skoroszyt używając konstruktora new,
Spreadsheet-WriteExcel do którego przekazujemy jako argument nazwę
Główną siłą napędową naszych raportów bę- naszego pliku helloexcel. xls. Potem tworzymy
idać to doskonale na przykładzie dzie moduł Spreadsheet-WriteExcel autorstwa arkusz i wreszcie na koniec, w komórce o adre-
raportów, gdzie w zależności od Johna McNamary. W chwili pisania tego arty- sie (0,0) wpisujemy napis powitalny.
Wtypu grupy odbiorców wymagane kułu, dostępna najnowsza wersja modułu nosi- Pierwszy program za nami, umiemy już
jest zastosowanie innego podejścia. O ile ad- ła oznaczenie 0.42. Za pomocą tego modułu utworzyć skoroszyt i arkusz oraz wyświetlać
ministratorzy w zupełności zadowalają się można generować binarne pliki w formacie napisy. Czas, żeby przyjrzeć się bliżej możli-
zwykłym plikiem tekstowym, o tyle dla od- Excela kompatybilne z wersjami Excel 5, 95, wościom oferowanym przez moduł Spreadshe-
biorcy biznesowego konieczne jest zastosowa- 97, 2000 i 2002. et-WriteExcel, a są one naprawdę niemałe.
nie bardziej wyszukanego formatu. Perl przy- Jak zaznacza w dokumentacji sam autor, Ogólnie rzecz biorąc, dostępne metody mo-
chodzi także i tutaj z pomocą, oferując gotowe
moduły do formatowania dokumentów np.
Listing 2. Przykłady definiowania szablonów formatowania
w XML, PDF, RTF czy choćby formacie Exce-
la. Właśnie temu ostatniemu poświęcony bę- 01 my $title = $workbook->addformat (); # tworzenie szablonu jako
dzie artykuł. obiektu o nazwie title
02 $title->set_font ('Arial CE'); # przyporządkowanie do szablonu
Dlaczego Excel? czcionki...
Właśnie, dlaczego Excel, skoro jest tyle in- 03 $title->set_size (14); # i wielkości czcionki
nych, być może ideowo bardziej słusznych for- 04 $title->set_bold (); # ustawienie typu na pogrubiony
05 my $head = $workbook->addformat (); # tworzenie innego szablonu
06 $head->set_bold ();
Listing 1. Hello Excel
07 $head->set_align ('center'); # tak możemy określić rozmieszczenie
01 #! /usr/local/bin/perl -w 08 $head->set_bottom (); # a tutaj ustawiamy wyświetlanie krawędzi
02 use Spreadsheet:: Write- komórek
Excel; # Krok 1 09 $head->set_top ();
03 my $workbook = Spreadshe- 10 $head->set_left ();
et:: WriteExcel->new ('hello- 11 $head->set_right ();
excel. xls'); 12 $head->set_text_wrap; # ta metoda powoduje, że tekst w komórce bę-
04 $worksheet = $workbook- dzie zawijany
>add_worksheet (); 13 my $numrow = $workbook->addformat ();
05 $worksheet->write (0,0, 14 $numrow->set_num_format ('# ### ##0.00'); # tak możemy definiować
'Hello Excel! '); wyświetlanie formatów liczbowych
06 $workbook->close (); 15 $numrow->set_right ();
78 Marzec 2004 www.linux-magazine.pl
Raportowanie w Perlu PROGRAMOWANIE
wowych metod przedstawionych w przykła-
Listing 3. Definiowanie rozmiarów pól
dach, możliwe jest m. in. ustawianie koloru
01 $worksheet->set_row (0, undef, $format1); # Zastosowanie formatu czcionek i wypełnienia komórek, osadzanie
dla wiersza bitmap, stosowanie formuł itd. Na szczęście
02 $worksheet->set_column ('A: A', 40, $format2); # Zastosowanie in- do modułu dołączona jest obszerna doku-
nego formatu dla kolumny 1 i ustawienie szerokości na 40 mentacja z licznymi przykładami, gdzie moż-
03 $worksheet->write ('A1', 'Hello'); # Wyświetlenie napisu na się zapoznać z interesującymi szczegóła-
w komórce A1 mi. My natomiast będziemy kontynuować
prace nad stworzeniem naszego raportu.
Przed przystąpieniem do wyświetlenia da-
dułu możemy podzielić na metody związane $report1 = $workbook->U nych pozostaje nam jeszcze określenie wielko-
z własnościami skoroszytu, arkusza, komórki, add_worksheet (); # Sheet1 ści komórek. Istnieją tutaj dwie główne meto-
układu strony i formatowania. Zanim zbudu- $report2 = $workbook->U dy pozwalające sprawować kontrolę nad wier-
jemy pierwszy funkcjonalny raport, przyjrzyj- add_worksheet U szami i kolumnami: set_row i set_column. No
my się bliżej niektórym z nich. ('Registered Customers'); U i wreszcie przystępujemy do wyświetlania za-
Bardzo istotną z punktu widzenia webowej # Registered Customers wartości komórek. Mamy tutaj do dyspozycji
(CGI) aplikacji raportującej jest możliwość metody: write (format ogólny), write_string (do
przekierowania standardowego wyjścia. Do te- To co najbardziej nadaje profesjonalizmu ra- wyświetlania łańcuchów tekstowych) i wri-
go celu wykorzystujemy specjalną nazwę pliku portowi, to jego wygląd, dlatego szczególną te_number (do wyświetlania liczb).
'-'. Dzięki temu zamiast zapisywać dane do pli- uwagę powinniśmy poświęcić zagadnieniom
ku, wysyłamy je za pośrednictwem serwera formatowania. Dysponujemy w tym zakresie Budujemy raport
WWW wprost do przeglądarki. praktycznie pełnym wachlarzem możliwości Przedstawione do tej pory metody są wystar-
Excela. Właściwości formatowania uzyskuje- czające do sporządzenia pierwszego raportu.
my $workbook = Spreadsheet:: U my poprzez grupowanie poszczególnych atry- Jedyne co nam pozostaje, to utworzenie inter-
WriteExcel->new ('-'); butów w szablony. Do tworzenia poszczegól- fejsu użytkownika i pobranie danych ze zró-
nych szablonów formatowania służy metoda dła, w naszym przypadku będzie nim relacyj-
Nie musimy się także przejmować obsługą add_format. Przykłady przedstawione na Li- na baza danych Open Source PostgreSQL.
bardziej złożonych raportów, składających się stingu 2 pozwalają zapoznać się ze sposobem Do połączenia z bazami danych w Perlu
z kilku arkuszy. Kolejne arkusze możemy do- tworzenia własnych szablonów. używane są moduły DBI i DBD. Biblioteka
dawać używając metody add_worksheet: To tylko część możliwości. Oprócz podsta- DBI to uniwersalny, ujednolicony interfejs
Listing 4. Przykład formularza raportu
01 Monthly Summary 22
02

Detailed list of name=year_from size=4 38
shipped books

maxlength=4> / 39 03
name=month_to size=2
action="booktown.pl"> 24 maxlength=2> /
04 25
05 name=month_from size=2 41 26 name=day_to size=2
08 name=day_from size=2 44
11
12 MM / 29 46
13 30 47 align=left>
15 DD 32 33 TO (date) value="Execute">
17 34 49
18
19 FROM (date) valign=center> 51
20 36
21

06
maxlength=2> / 42 07 27 maxlength=2>
09 YYYY / 28
10
maxlength=2> 45
14 31
48 16
35
valign=center> maxlength=4> / 54
www.linux-magazine.pl Marzec 2004 79
Raportowanie w Perlu
PROGRAMOWANIE
baz danych, dzięki któremu można Pobieranie danych
uzyskać dostęp do danych składowa- do raportu
nych w bazach różnych typów. DBD Jedyne co nam pozostało do zrobienia
natomiast jest dedykowanym sterow- w tym momencie, to pozyskanie da-
nikiem do konkretnej bazy danych, za- nych. Załóżmy, że mamy już przygo-
pewniającym komunikację między in- towane zapytanie SQL. W takim razie
terfejsem DBI i bazy danych. W przy- w skrypcie najpierw musimy obsłużyć
padku PostgreSQL mamy do dyspozy- odbiór danych przesłanych z formula-
cji sterowniki DBD:: Pg i DBD:: PgPP rza. Do tego celu doskonale nadaje się
(dla baz Oracle istnieje bardzo dobry funkcja param z modułu CGI. pm
sterownik DBD:: Oracle). (pierwsza część skryptu Listing 5).
Co do interfejsu użytkownika, to Otrzymane dane poddajemy obróbce
dobrym pomysłem wydaje się zasto- funkcji chomp, aby obciąć ewentualne
sowanie technologii intranetowej, Rysunek 1. Formularz osadzony na stronie WWW. znaki końca linii, a następnie skleja-
która jest bardzo elastyczna i wygod- my, przygotowując w ten sposób dane
na (nie wymaga instalowania dodatkowego czątkową i końcową, które byłyby przekazywa- do podstawienia do zapytania SQL.
oprogramowania na stacjach roboczych). ne mechanizmem CGI do skryptu w Perlu, Połączenie z bazą odbywa się w sposób typo-
Pozwoli to ponadto na sparametryzowanie gdzie podstawiane byłyby następnie do zapy- wy dla DBI. Najpierw tworzymy uchwyt $dbh,
wykonywanych raportów. W dalszej części tania SQL. Kod przykładowego formularza poprzez połączenie z bazą danych za pomocą
artykułu przedstawiony zostanie sposób mógłby być na przykład taki, jak przedstawio- sterownika PgPP. Następnie tworzymy
budowy kompletnego raportu. Załóżmy, że no na Listingu 4. uchwyt dyrektywy $sth przygotowującej zapy-
będzie to raport wspomagający pracę księ- Dane z formularza: year_from, month_from, tanie SQL i wykonujemy je  $sth->execute ().
garni, a jego zadaniem będzie udzielanie day_from oraz year_to, month_to, day_to prze- Wyniki zwrócone zapytaniem SQL pobieramy
informacji o sprzedaży książek w określo- kazywane są metodą POST do skryptu wyko- wsadowo, korzystając z metody fetchall_array-
nym przedziale czasu. nawczego booktown. pl. Wygląd formularza ref (). Metoda ta pobiera cały zestaw wynikowy
osadzonego na stronie WWW przedstawia do struktury danych Perla, którą możemy po-
Interfejs użytkownika Rysunek1. Jak widać, wykorzystując opisywa- tem dowolnie obrabiać. Następnie zamykamy
Biorąc pod uwagę powyższe założenia, może- ny w artykule mechanizm można pokusić się uchwyt dyrektywy i uchwyt połączenia, koń-
my przystąpić do budowy interfejsu formula- o stworzenie szerszego systemu raportowania, cząc pracę z bazą danych. Teraz możemy już
rza HTML. Formularz pobierałby daty: po- obejmującego całościowe potrzeby firmy. śmiało przystąpić do generowania raportu.
Listing 5. Pierwsza część skryptu  pobieranie danych
01 #!/usr/local/perl/bin/perl -w 21 43 stock st,
02 use strict; 22 chomp ($yf); 44 subjects su
03 use DBI; 23 chomp ($mf); 45 WHERE
04 use CGI qw(:standard); 24 chomp ($df); 46 s.isbn=e.isbn
05 use Spreadsheet::WriteExcel; 25 chomp ($yt); 47 AND e.book_id=b.id
06 26 chomp ($mt); 48 AND b.subject_id=su.id
07 ### Parametry konfiguracyjne 27 chomp ($dt); 49 AND e.isbn=st.isbn
### 28 50 AND s.ship_date between
08 ### polaczenia z baza 29 my $date_f="$yf" . "-" . ('$date_f') AND ('$date_t')
09 my $dbname="booktown"; "$mf" . "-" . "$df"; 51 ORDER BY
10 my $login="postgres"; 30 my $date_t="$yt" . "-" . 52 su.subject ASC";
11 my $pass="postgres"; "$mt" . "-" . "$dt"; 53
12 31 54 ### Polaczenie z baza i
13 my 32 ### Zapytanie SQL ### pobranie danych ###
$ExcelFile='booktown_report.x 33 my $sel="SELECT 55 my $dbh=DBI-
ls'; 34 s.ship_date, >connect("dbi:PgPP:$dbname",
14 ### Odbior danych z 35 b.title, $login, $pass);
formularza WWW ### 36 e.isbn, 56 my $sth=$dbh->prepare($sel);
15 my $yf=param("year_from"); 37 su.subject, 57 $sth->execute();
16 my $mf=param("month_from"); 38 st.cost 58 my $wyniki = $sth-
17 my $df=param("day_from"); 39 FROM >fetchall_arrayref();
18 my $yt=param("year_to"); 40 shipments s, 59 $sth->finish();
19 my $mt=param("month_to"); 41 editions e, 60 $dbh->disconnect;
20 my $dt=param("day_to"); 42 books b,
80 Marzec 2004 www.linux-magazine.pl
Raportowanie w Perlu PROGRAMOWANIE
Generowanie pliku Excel Wreszcie przystępujemy do wy-
Ponieważ raport będzie generowany po stronie prowadzenia samych danych. Naj-
serwera WWW, pierwszą czynnością przed pierw wyodrębniamy poszczególne
rozpoczęciem generowania właściwego pliku, wiersze ze złożonej struktury da-
powinno być wysłanie do przeglądarki infor- nych @$wyniki, będącej referencją
macji o typie MIME (Listing 6). Do tego celu do tablicy zmiennej $item, a z niej
służą poniższe informacje nagłówka, wypisy- z kolei w podobny sposób wydoby-
wane zwykłym poleceniem print. wamy wartości poszczególnych pól.
Wartości pól wypisujemy w pętli
print  Content-type: U w standardowy sposób, korzystając
application/vnd. ms-excel\n ; z metody write (). Na zakończenie
print  Content-Disposition: U zamykamy uchwyt arkusza. Rezul-
attachment; U tat działania skryptu jest przedsta-
filename=$ExcelFile\n\n ; wiony na Rysunku 2.
W dalszej kolejności korzystamy z poznanych Podsumowanie Rysunek 2. Gotowy raport w postaci pliku Excel.
już wcześniej metod modułu Spreadsheet-Wr- Wykorzystując opisaną w tekście
iteExcel. Tworzymy uchwyt arkusza i skoro- metodę sporządzania raportów, można zbu- oprócz prostoty i dużej szybkości tworzenia
szytu, określamy rozmiary kolumn, definiuje- dować kompletne środowisko raportowe, raportów, jest możliwość sięgania do róż-
my formaty. Następnie wypisujemy tytuł będące w stanie zaspokoić dowolne potrze- nych baz danych i niezależność od platfor-
i tworzymy nagłówki kolumn. by raportowe firmy. Jej największą zaletą, my systemowej. %
Listing 6. Druga część skryptu  generowanie pliku w formacie Excel
01 ### Generowanie raportu ### 26 $header->set_right(); 48 $rap ->write(3, 3, "ISBN No",
02 print "Content-type: 27 $header->set_text_wrap; $header);
application/vnd.ms-excel\n"; 28 49 $rap ->write(3, 4,
03 print "Content-Disposition: 29 my $num = $workbook- "Category", $header);
attachment; >addformat(); 50 $rap ->write(3, 5, "Price",
filename=$ExcelFile\n\n"; 30 $num->set_num_format('# ### $header);
04 ##0.00'); 51
05 my $workbook = 31 52 my $line=4;
Spreadsheet::WriteExcel- 32 my $toright = $workbook- 53 my $no=1;
>new("-"); >addformat();
06 my $rap = $workbook- 33 $toright->set_align('right'); 54 foreach my $item (@$wyniki) {
>addworksheet("Summary"); 34 55 my
07 35 my $toleft = $workbook- ($shipdate,$booktitle,$isbn,$
08 $rap ->set_column(0, 0, 6); >addformat(); category,$price) = @$item;
09 $rap ->set_column(1, 1, 26); 36 $toleft->set_align('left'); 56 $rap ->write($line, 0, $no,
10 $rap ->set_column(2, 2, 28); 37 $toright);
11 $rap ->set_column(3, 3, 12); 38 my $center = $workbook- 57 $rap ->write($line, 1,
12 $rap ->set_column(4, 4, 18); >addformat(); $shipdate, $center);
13 $rap ->set_column(5, 5, 8); 39 $center->set_align('center'); 58 $rap ->write($line, 2,
14 40 $booktitle, $center);
15 my $title = $workbook- 41 my $cap = $workbook- 59 $rap ->write($line, 3,
>addformat(); >addformat(); $isbn, $toright);
16 $title->set_font("Arial CE"); 42 $cap->set_font("Arial CE"); 60 $rap ->write($line, 4,
17 $title->set_size(14); 43 $cap->set_size(8); $category, $center);
18 $title->set_bold(); 44 $rap ->write(0, 0, "Booktown 61 $rap ->write($line, 5,
19 Detailed Report: $date_f - $price, $num);
20 my $header = $workbook- $date_t", $title); 62
>addformat(); 45 $rap ->write(3, 0, "No", 63 $line++;
21 $header->set_bold(); $header); 64 $no++;
22 $header->set_align('center'); 46 $rap ->write(3, 1, "Ship 65 }
23 $header->set_bottom(); date", $header); 66
24 $header->set_top(); 47 $rap ->write(3, 2, "Book 67 $workbook->close();
25 $header->set_left(); title", $header);
www.linux-magazine.pl Marzec 2004 81


Wyszukiwarka

Podobne podstrony:
Kurs programowania w Perl u
Perl Zaawansowane programowanie
mod perl Podrecznik programisty modpkp
Perl Zaawansowane programowanie Wydanie II perlz2
Perl Testowanie Zapiski programisty
Perl Mistrzostwo w programowaniu perlmp
zestawy cwiczen przygotowane na podstawie programu Mistrz Klawia 6
Międzynarodowy Program Badań nad Zachowaniami Samobójczymi
CSharp Introduction to C# Programming for the Microsoft NET Platform (Prerelease)
Instrukcja Programowania Zelio Logic 2 wersja polska

więcej podobnych podstron