Reporting tool in ambiente Open Source

Transcript

Reporting tool in ambiente Open Source
Alma Mater Studiorum
Università degli Studi di Bologna
Facoltà di Scienze Matematiche, Fisiche e Naturali
Corso di Laurea in Informatica
Materia di Tesi: Sistemi di Elaborazione II
Reporting tool in ambiente Open Source
Tesi di Laurea Specialistica di
Giulio Toffoli
Relatore
Prof. Alessandro Amoroso
II Sessione
Anno Accademico 2002-2003
Cinque parole chiave:
Reporting tool, visual builder, java printing, JasperReports, iReport
Reporting tool in ambiente Open Source - Pagina 2 di 84
A mia moglie Caterina
Reporting tool in ambiente Open Source - Pagina 3 di 84
Reporting tool in ambiente Open Source - Pagina 4 di 84
Sommario
1. Introduzione ......................................................................................... 7
2. Cos’è un reporting tool ..................................................................... 12
2.1 Struttura di un report ed elementi grafici ............................................ 12
2.2 Collegamento dei dati ........................................................................ 16
2.3 Esportazione della stampa................................................................. 19
2.4 Integrazione dei report all’interno di un’applicazione ......................... 19
2.5 Tipologie di report e strutture complesse ........................................... 20
2.6 Alcune note su performance e produttività......................................... 22
2.7 Linguaggi di programmazione e reporting tool ................................... 23
3. JasperReports.................................................................................... 24
3.1 Funzionamento di JasperReports ...................................................... 26
3.2 Struttura del report secondo jasper ed elementi grafici...................... 30
3.3 Campi, variabili, parametri ed espressioni ......................................... 37
3.4 L’interfaccia JRDataSource ............................................................... 39
3.5 Integrare JasperReports in un progamma java .................................. 43
3.5.1 Compilazione di un report ............................................................. 43
3.5.2 Esempio di creazione di una JRResultSetDataSource ................. 44
3.5.3 Generazione della stampa ............................................................ 45
3.5.4 Visualizzazione di una stampa a video ......................................... 46
3.5.5 Esportazione di una stampa in un file ........................................... 46
4. iReport ................................................................................................ 48
4.1 iReport e JasperReports .................................................................... 56
4.2 L’interfaccia principale ....................................................................... 57
4.3 Bande ed elementi ............................................................................. 60
4.4 Definizione di una fonte dati............................................................... 70
4.4.1 Empty data source (JREmptyDataSource).................................... 71
4.4.2 XML Data source .......................................................................... 71
4.4.3 JavaBean Set Datasource............................................................. 71
4.4.4 Custom Datasource ...................................................................... 72
4.4.5 Impostazione di una connessione JDBC....................................... 73
4.5 Recupero dei campi mediante SQL ................................................... 74
4.6 Gestione di variabili e parametri......................................................... 75
Reporting tool in ambiente Open Source - Pagina 5 di 84
4.7 Compilazione ed esportazione........................................................... 75
4.8 Performance ...................................................................................... 76
4.9 Un caso di studio: Sydran Services LLC............................................ 77
4.9.1 Storia di Cheetah .......................................................................... 77
4.9.2 Obiettivo raggiunto ........................................................................ 79
4.10 Sviluppi futuri ................................................................................... 80
Conclusioni ............................................................................................ 81
Bibliografia ............................................................................................. 83
Reporting tool in ambiente Open Source - Pagina 6 di 84
1. Introduzione
A qualunque programmatore è capitato almeno una volta nella vita di
dover sviluppare delle funzionalità di stampa per un qualche programma.
A differenza di quanto accade per la costruzione delle interfacce grafiche,
il supporto alla stampa offerto dai più diffusi ambienti di sviluppo è davvero
primitivo. Nella maggior parte dei casi lo sviluppatore ha a disposizione un
buffer di memoria (la pagina che dovrà stampare) ed una serie più o meno
variegata di primitive che gli permetteranno di tracciare poligoni, scrivere
caratteri con i font più congeniali, copiare immagini e, se fortunato,
giustificare intere porzioni di testo. È davvero poco; tuttavia un qualsiasi
altro strumento di più alto livello offerto al programmatore per costruire le
stampe, in un modo o nell’altro limiterà le potenzialità offerte dall’approccio
per così dire “rude” delle primitive grafiche.
Eppure strumenti per lo sviluppo di stampe ad alto livello esistono, ed al
contrario di quanto si potrebbe immaginare, sono molto diffusi, ma poco
usati. Si noti che non stiamo parlando di word processor o di programmi
creati per stampare documenti, ma di strumenti di sviluppo che affianchino
il programmatore nella produzione di funzionalità di stampa.
Lo strumento per la creazione dei report fornito con il noto programma
Microsoft Access è un diffusissimo esempio di reporting tool (in italiano la
traduzione suona un po’ male, ma azzarderemo comunque il nome di
“strumento di reportistica”). A differenza degli strumenti che vedremo in
questa tesi, Access è un reporting tool un po’ particolare: è possibile
utilizzarlo solo all’interno di Access stesso, non nasce come strumento di
supporto allo sviluppo di stampe per altri linguaggi (se non in qualche
modo per il Visual Basic, per altro unico ambiente di sviluppo a fornire un
proprio strumento di reportistica), ma permette all’utente di comporre con
Reporting tool in ambiente Open Source - Pagina 7 di 84
la stessa facilità con la quale oggi si crea un’interfaccia grafica, una
stampa, con gestione automatizzata di formule, pagine, salti pagina,
giustificazione del testo ecc…
Il lettore attento si sarà già reso conto che un approccio a così alto livello
nella costruzione del report potrà soddisfare le esigenze richieste solo da
poche tipologie di stampa, in particolare la stampa di documenti la cui
struttura può essere ricondotta ad una sorta di template. In sostanza con
uno strumento di reportistica come quello offerto da Access non si potrà
mai (se non usando opportuni trucchi) realizzare le stampe prodotte da un
CAD o ad esempio da un programma di grafica vettoriale e tanto meno si
potrà mai raggiungere la flessibilità di un word processor sufficientemente
evoluto.
Tuttavia, il nostro obiettivo non è certo quello di inventare un reporting tool
universale e adatto a qualsiasi esigenza. Al contrario potremmo in qualche
modo limitare in maniera molto più forte il nostro campo d’azione ed
affermare che in questa tesi parleremo di reporting tool per lo sviluppo di
stampe che visualizzano informazioni organizzate in una struttura
tabellare (o in una struttura riconducibile ad una forma tabellare).
Gli strumenti di reportistica di questo tipo sono di fatto i più diffusi; dato il
loro largo impiego in programmi di tipo gestionale, ovvero in programmi
che fino a poco tempo fa avevano poco o nulla a che fare con il mondo
open source, la loro natura è quasi esclusivamente commerciale. Forse il
software che in assoluto ha maggiormente dettato le regole nel panorama
mondiale degli strumenti di reportistica nel corso degli anni è Crystal
Report della Crystal Decisions Inc.[5]. La sua popolarità è dovuta in gran
parte alla distribuzione di una versione speciale all’interno del Visual Basic
di Microsoft, ed ha riscosso negli anni grandissimo successo, godendo di
un elevato numero di utenze. Esiste anche una versione java (molto
diffusa, ma non altrettanto apprezzata come la versione per Visual Basic).
Circa due anni fa, dovendo sviluppare dei report per un applicativo web
basato sulla piattaforma J2EE, iniziai ad effettuare una ricerca degli
strumenti che potessero in qualche modo velocizzare la creazione delle
stampe. L’idea era quella di visualizzare la stampa in formato pdf
Reporting tool in ambiente Open Source - Pagina 8 di 84
all’interno del browser stesso, pertanto le primitive di stampa offerta da
java non vennero nemmeno mai prese in considerazione. La scelta
ricadde su una libreria open source per la generazione di PDF, RTF ed
HTML: iText. Oggi iText è la libreria open source per la generazione di pdf
più diffusa nel mondo java, ma due anni fa le funzionalità offerte dalla
libreria erano decisamente più limitate, tanto che per generare a fondo
pagina la scritta “pagina x di n”, era necessario produrre la stampa due
volte, una per conoscere il numero di pagine totali, un’altra per produrre la
stampa definitiva con il numero n opportunamente sostituito con il valore
appena ricavato. Tuttavia le righe di codice necessarie a produrre una
stampa discreta era più che accettabile.
Non mi occupai più di stampe fino ad un anno fa, quando, ripresentandosi
la stessa necessità dell’anno precedente, finii nuovamente sul sito di iText.
La strada fatta dalla libreria in meno di un anno mi lasciò gradevolmente
stupito. Bruno Lowagie (l’autore di iText), affiancato da Paul Soares
avevano ristrutturato la libreria aggiungendo funzionalità davvero potenti,
ma
dall’utilizzo
abbastanza
complesse
e
non
immediatamente
comprensibile dagli esempi a corredo (per altro molto ben fatti).
Qualche mese prima aveva preso il via un altro progetto open source
chiamato JasperReports. L’autore Teodor Danciu aveva sviluppato una
libreria per la generazione di documenti esportabili in diversi formati (pdf,
html, xsl,…) a partire da una definizione in formato XML del layout. In
particolare l’esportazione in formato pdf veniva effettuata mediante la
libreria iText.
Grosso modo nello stesso periodo nacquero almeno altri due strumenti di
reportistica open source: JFreeReport e DataVision, il primo utilizzava una
logica molto simile a quella di JasperReports, basando la definizione delle
stampe su documenti XML, il secondo, invece, rappresenta probabilmente
il primo esempio di reporting tool in ambiente open source completamente
ispirato a Crystal Report, dotato di un’interfaccia grafica per la
composizione visuale dei report.
Tuttavia la mia attenzione si focalizzò su JasperReports, in parte, devo
ammetterlo, anche colpito dagli esempi a corredo della libreria che ne
mettevano in risalto tutte le notevoli funzionalità e qualità. L’assenza di
Reporting tool in ambiente Open Source - Pagina 9 di 84
un’interfaccia grafica simile a quella offerta da DataVision per la
generazione dei report era sopperita da diversi strumenti rigorosamente
open source nati poco dopo la comparsa di Jaspereports: “Designer for
Jasper” di Jackie Manning e “JasperEdit” di Erik Swenson, autore anche di
“Jeez”, un editor per JasperReports sviluppato come plugin per Eclipse
(un diffuso IDE open source nato da un consorzio di “big” del mondo
dell’IT e del quale IBM è la punta di diamante).
“Designer for Jasper” si rivelò un programma pressochè inutilizzabile date
le scarse qualità di editor visuale e l’incredibile lentezza dovuta alla
pesantezza dell’interfaccia swing (la libreria standard per le interfacce
grafiche di java).
JasperEdit, invece, permetteva soltanto l’editing dell’XML in una sorta di
modalità assistita (highlighting del codice e completamento automatico dei
tag) e la possibilità di ottenere un preview del layout, ma non lo si poteva
certo chiamare un editor visuale.
Fu così che decisi di iniziare a scriverne uno mio, un nuovo editor per la
creazione e la generazione di stampe basato su JasperReports; uno
strumento pensato per gli sviluppatori, in grado di svincolarli dalla
necessità di dover imparare la non banale sintassi XML di JasperReports.
Nacque così iReport, divenuto oggi uno dei più evoluti ed utilizzati
reporting tool in ambiente open source. Nato per l’ambiente java, iReport e
JasperReports vengono utilizzati anche in progetti web sviluppati in
ambienti differenti da J2EE, come PHP e Perl.
Prima di entrare nel vivo della discussione, ci terrei a fare alcune
precisazioni sulle pagine che seguiranno. Tenterò di essere sempre il più
obiettivo possibile dell’esprimere giudizi relativi ai diversi strumenti di
reportistica citati nel testo, tuttavia, come sviluppatore di iReport e forte
sostenitore di JasperReports, potrei talvolta venire meno a questa
obiettività o comunque esprimere giudizi non universalmente condivisi.
Essendomi imbattuto in decine di discussioni relative al confronto dei
diversi software di reportistica, ho notato come i sostenitori di un
particolare prodotto, a causa di una scarsa conoscenza dei prodotti
concorrenti, cadono nell’errore di sminuire le funzionalità di quest’ultimi. In
Reporting tool in ambiente Open Source - Pagina 10 di 84
realtà questo genere di programmi è mediamente molto complesso, e solo
un pesante uso della singola soluzione permette di comprenderne le reali
potenzialità
e
sufficientemente
personalmente
non
ritengo
di
aver
utilizzato
prodotti diversi da JasperReports da poter dire con
certezza che taluni problemi non siano risolvibili con tali prodotti. D’altro
canto, conoscendo fin troppo bene JasperReports, ed in qualità di
sviluppatore di uno strumento di reportistica, potrei cadere anche
nell’errore opposto, ovvero considerare scontate talune funzionalità che
potrebbero essere tutt’altro che accessibili all’utente medio (perché non
intuitive o utilizzabili solo grazie ad approfondita conoscenza del
funzionamento interno della libreria). Più di una volta, infatti, mi è capitato
di dover rinunciare a spiegare la soluzione di un problema ad utenti poco
esperti essendo questa fuori dalla loro portata.
Infine potrà capitare che i capitoli riguardanti JasperReports e iReport
assumano in alcuni passi toni da manuale. La cosa sarà assolutamente
intenzionale, volendo cogliere l’occasione di questa tesi per integrare la
scarsissima documentazione relativa all’uso ed alle caratteristiche di
iReport.
Reporting tool in ambiente Open Source - Pagina 11 di 84
2. Cos’è un reporting tool
In generale è difficile definire con chiarezza che cosa sia un reporting tool,
in quanto questi rappresentato spesso strumenti che completano software
più ampi quali ambienti di sviluppo o programmi di gestione di un DBMS,
ecc... Tuttavia una buona definizione potrebbe essere la seguente: un
reporting tool è un sistema che permette di definire il layout di una stampa,
generarla popolando il layout con dei dati dinamici ed esportare il risultato
finale in un qualche formato di pubblicazione.
Da questa definizione appare chiaro che un reporting tool è costituito da
tre componenti separati: il componente per la definizione del layout, il
componente in grado di fondere questo layout con i dati da stampare, ed
un ultimo componente che permetta l’esportazione della stampa finita nel
formato richiesto.
2.1 Struttura di un report ed elementi grafici
La descrizione di come debbano essere organizzati i dati sul nostro
documento viene realizzata elaborando un layout.
Il layout definisce la struttura del nostro report ed è costituito da un
insieme di porzioni orizzontali di documento, dette bande (o sezioni),
all’interno delle quali vengono inseriti gli elementi grafici che comporranno
il contenuto della nostra stampa. Tutti gli strumenti di reportistica
prevedono che il layout sia diviso in almeno cinque bande: report header,
page header, detail, page footer e report footer. Come si può intuire dal
nome, ogni banda si riferisce ad una specifica porzione di una “pagina
Reporting tool in ambiente Open Source - Pagina 12 di 84
tipo” del nostro documento. Oltre a queste cinque bande di base, possono
essere presenti altre bande che realizzano il raggruppamento delle
informazioni: i group header e i group footer.
Fig.2.1: Struttura del layout
Quando il report viene popolato, il programma che genera la stampa
compone il risultato finale “ripetendo” le diverse porzioni definite nel layout
in base ai dati da visualizzare e alle regole specificate dallo sviluppatore.
In figura 2 è possibile vedere il risultato di un’ipotetica stampa generata a
partire dal layout mostrato in figura 1.
All’interno delle bande compaiono degli oggetti grafici chiamati elementi. Il
set minimo di elementi che un reporting tool dovrebbe mettere a
disposizione è molto limitato e si riduce a:
-
Casella di testo
-
Immagine
-
Poligono (linea, rettangolo, ovale)
Questi pochi elementi sono sufficienti a definire stampe anche molto
complesse. Esiste poi un elemento speciale che permette di incapsulare
un report un altro: il sottoreport.
Non tutti gli strumenti di reportistica sono in grado di gestire i sottoreport, e
pochi sono quelli in grado di gestire i sottoreport ricorsivamente. Questa è
una delle caratteristiche che elegge JasperReports al miglior strumento di
Reporting tool in ambiente Open Source - Pagina 13 di 84
generazione di report disponibile nel mondo open source, essendo l’unico
Fig.2.2: Il risultato della stampa generata mediante il layout in figura 1
strumento di questo tipo a gestire i sottoreport.
Ogni strumento di reportistica contempla poi una serie di altri elementi in
qualche modo derivabili dai precedenti ed utilizzabili liberamente
all’interno di una stampa. Uno dei più diffusi è l’oggetto “chart” o “grafico”.
Poiché
il
grafico
può
essere
banalmente
rappresentato
come
un’immagine, tutti gli strumenti di reportistica open source (a differenza di
quanto avviene per prodotti analoghi di tipo commerciale), delegano le
funzionalità di “charting” a librerie esterne (tipicamente open source) nate
esclusivamente con lo scopo di generare grafici visualizzati nel report
come oggetti immagine (molto diffusi sono i pacchetti open source:
JFreeChart e JCharts, ma ce ne sono molti altri disponibili anche per
linguaggi di programmazione diversi da java). In pratica nessuno
strumento open source di reportistica supporta nativamente l’elemento
Reporting tool in ambiente Open Source - Pagina 14 di 84
“chart”, ma ciò non impedisce di visualizzare grafici all’interno delle nostre
stampe…
In generale, l’elemento immagine può essere visto come una sorta di
viewport utilizzabile per il rendering di qualsiasi cosa. A sfruttare questo
meccanismo sono molti elementi “inconsueti” quali, oltre ai grafici,
generatori di codici a barre, strumenti di disegno vettoriale, ecc…
I tipi di dati stampabili mediante un sistema di reportistica di questo tipo
sono , in definitiva, tutti quelli riconducibili ad un testo (stringhe e numeri) e
quelli rappresentabili mediante un’ immagine (foto, grafici, codici a
barre,…). Il binding tra i particolari dati da stampare e gli elementi che li
contengono viene normalmente effettuato mediante delle formule.
Praticamente tutti i sistemi di reportistica definiscono il valore che deve
essere rappresentato da un certo elemento sotto forma di un’espressione,
che permetterà non solo di specificare il dato da stampare, ma anche di
effettuare “al volo” elaborazioni dei dati stessi come somme, medie, ecc…
Le funzionalità che permettono di dare dinamicità ai report (per l’appunto
sommatorie, medie, raggruppamenti, ecc…) sono pressochè simili per
qualsiasi strumento di reportistica sufficientemente potente. Tuttavia la
scelta implementativa adottata dai diversi strumenti è tutt’altro che simile.
L’idea di base comune è di appoggiarsi ad un linguaggio dotato di una
certa espressività e potenza, ma la scelta del linguaggio cambia
completamente il modo di scrivere formule e collegare dati ad elementi.
Curiosa la scelta adottata dal creatore di DataVision che utilizza come
linguaggio di formule Ruby, un diffuso linguaggio di scripting open source.
JasperReports si appoggia direttamente alla potenza di java arricchito,
come vedremo, di qualche nozione sintattica per realizzare in modo
semplice il binding con i dati.
Il componente che permette di definire il layout è generalmente costituito
da un ambiente visuale tramite il quale è possibile collocare e gestire tutti
gli elementi che compongono un report. Nel caso specifico di
JasperReports e JFreeReport, il layout viene definito mediante una
speciale sintassi XML. Gli sviluppatori, in questi due casi, si sono
elegantemente svincolati dall’onere di dover scrivere un complesso e
oneroso ambiente visuale per la definizione del layout, concentrandosi
Reporting tool in ambiente Open Source - Pagina 15 di 84
sulle funzionalità messe a disposizione delle proprie librerie per la
generazione della stampa.
In effetti creare strumenti in grado di coprire tutti i possibili aspetti della
definizione del layout non è semplice. Molti degli strumenti commerciali
che si discostano in parte dal modello reso famoso da Crystal Report
risultano essere frustanti e tutt’altro che intuitivi.
2.2 Collegamento dei dati
La potenza e la qualità di un reporting tool non è data solo dal numero e
dall’utilità degli elementi disponibile per creare una stampa. Come
abbiamo visto, con pochissimi elementi siamo già in grado di realizzare
stampe molto complesse che soddisferanno il 90% delle capacità
espressive normalmente richieste da un software di reportistica. Un nodo
cruciale, piuttosto, risulta essere la facilità con cui è possibile “agganciare”
al nostro report una fonte dati. Fino a qualche anno fa, l’unica fonte dati
realmente utilizzata da un software di reportistica era una query SQL,
ovvero, i dati del mio documento erano rappresentati da dei campi
risultanti da una selezione effettuata mediante SQL. Oggi il binding dei
dati ad un report realizzato mediante una query SQL non solo è dato per
scontato, ma è quasi superato. Una fonte dati, infatti, può avere infinite
forme come una collezione di oggetti o un documento XML. Per questo
tutti gli strumenti di reportistica maggiormente evoluti mettono a
disposizione dell’utente una serie di “driver” appositamente studiati per
convertire i dati provenienti da sorgenti eterogenee esterne in dati
utilizzabili all’interno della nostra stampa.
Come per il caso degli elementi “chart”, il mondo open source in qualche
modo viene in contro agli sviluppatori dei reporting tool. Questi, infatti,
devono semplicemente sviluppare un’interfaccia comune da estendere per
la realizzazione di driver di fonti dati. Ci penseranno altri sviluppatori a
scrivere e rendere disponibili i driver per le fonti più disparate. È il caso di
JasperReports per il quale sono state scritte “data source” davvero
Reporting tool in ambiente Open Source - Pagina 16 di 84
particolati come quella per collegare dati provenienti da Hibernate (un
potente database ad oggetti open source).
Nella maggior parte delle implementazioni, queste fonti dati espongono
un’interfaccia simile a quella della classe ResultSet di java, ovvero una
sorta di struttura dati organizzata in righe e colonne. Il core del reporting
tool, ovvero il componente che si occuperà di popolare il layout attingendo
i dati dalla data source, processerà le righe una ad una utilizzando i valori
contenuti nelle varie colonne (i campi) per interpretare le espressioni
contenute negli elementi del report.
Sfortunatamente la rappresentazione dei dati in forma tabellare costituisce
un grosso limite qualora i dati siano organizzati in una struttura ad albero,
tipica dei documenti XML. Solo una parte di strutture ad albero possono
essere ricondotte in maniera semplice ad una forma tabellare. Si consideri
ad esempio la struttura ad albero di figura 2.3. Essendo gli elementi 1 e 2
sullo stesso ramo è necessario effettuare un merge dei rami.
La tabella in figura 2.4 potrebbe rappresentare una soluzione al nostro
problema, ma come si nota, il numero di record cresce molto rapidamente
e le performance del nostro strumento di reportistica crollano. Il modo più
efficiente per affrontare casi come questo è sempre l’utilizzo dei
sottoreport.
Root
Element 1
Element 1.1
Element 1.2
Element 2
Element 2.2
Element 2.3
Fig.2.3: Esempio di struttura dati ad albero
Reporting tool in ambiente Open Source - Pagina 17 di 84
Root
Element 1
Element 1.1
Element 2
Element 2.1
Root
Element 1
Element 1.1
Element 2
Element 2.2
Root
Element 1
Element 1.2
Element 2
Element 2.1
Root
Element 1
Element 1.2
Element 2
Element 2.2
Fig.2.4: Rappresentazione tabellare della struttura ad albero di figura 3
Tutti gli strumenti di reportistica processano sempre un record per volta.
Questo impedisce di accedere mediante le formule ai valori assunti dai
campi del record precedente o successivo a quello in corso di
elaborazione: l’accesso ai dati è limitato quindi al record corrente. Un caso
limite, ma non poco diffuso, e soprattutto particolarmente penalizzato da
questo meccanismo, è il seguente. Supponiamo di registrare ad intervalli
regolari il numero di chilometri percorsi da un auto (leggendo il valore dei
km totali percorsi sul contachilometri). Supponiamo ora di voler
visualizzare in un report tre colonne: nella prima metteremo la data di
registrazione del tempo, nella seconda il numero di chilometri progressivi
letti dal contachilometri, ed infine, nella terza, il numero di chilometri
parziali percorsi dall’auto tra la registrazione corrente e quella precedente.
L’ultima colonna descritta non può essere calcolata mediante formule, ma
necessita di un dato già calcolo (solitamente dal programma che produce i
dati da stampare), infatti siamo in grado di accedere al valore attuale del
tempo di registrazione, ma non più a quello precedente!. Esistono tuttavia
dei trucchi per poter memorizzare i dati in variabili temporanee, ma non
tutti gli strumenti di reportistica permettono di definire variabili o
meccanismi di memorizzazione intermedia delle informazioni processate.
Reporting tool in ambiente Open Source - Pagina 18 di 84
2.3 Esportazione della stampa
Il report appena generato viene solitamente memorizzato in un formato
intermedio gestito direttamente dallo specifico reporting tool, che mediante
dei meccanismi interni potrà convertirlo o, come si usa dire, esportarlo in
un formato di pubblicazione “standard”. I formati più diffusi sono il pdf,
l’HTML e l’ XML, oltre al supporto diretto per la stampa e l’anteprima a
video.
Il modello a driver descritto per l’accesso ai dati si utilizza anche per quel
che riguarda l’esportazione del report nei diversi formati. Anche in questo
caso JasperReports si rivela la libreria più flessibile, mettendo a
disposizione del programmatore un’interfaccia standard da implementare
per poter realizzare il proprio driver di esportazione, operazione facilitata
grazie anche alla disponibilità del codice sorgente dei driver distribuiti con
la libreria stessa, in grado di generare report nei formati più diffusi con
un’ottima resa finale (pdf, html, xsl, txt, xml).
2.4 Integrazione dei report all’interno di un’applicazione
Tutti i reporting tool mettono a disposizione una libreria (nel caso di java,
un archivio jar) che espone una serie di metodi per caricare una stampa,
eseguirla ed esportarla o visualizzarla a video. Per facilitare la vita agli
sviluppatori, gli autori delle varie librerie di reportistica hanno ridotto al
minimo la complessità del codice richiesto per eseguire le operazioni
citate. Normalmente un programma deve occuparsi di produrre la fonte
dati (in molti casi la fonte dati viene implicitamente creata dallo stesso
reporting tool a partire da una connessione ad un database aperta dal
programma stesso e passata alla libreria che eseguirà autonomamente
una query SQL, precedentemente memorizzata all’interno del report in
fase di creazione); creata la fonte dati, l’applicazione dovrà specificare il
report da generare (tipicamente memorizzato in un file) ed eseguire la
generazione della stampa. Un’ultima chiamata ad un metodo di
esportazione completa il codice di stampa.
Reporting tool in ambiente Open Source - Pagina 19 di 84
In effetti il numero di righe di codice richiesto per integrare in un
programma le funzionalità di stampa messe a disposizione dalla libreria di
un reporting tool (esclusa la creazione della fonte dati), no supera mai la
decina e le possibilità di estensione delle librerie open source in questo
specifico frangente permettono di sopperire anche alle richieste più
esigenti di integrazione con l’applicativo (essendone disponibile il codice).
2.5 Tipologie di report e strutture complesse
Probabilmente scrivere il codice per produrre una stampa esteticamente
molto piacevole e organizzata come una tabella è più che fattibile senza
l’ausilio di un reporting tool, anche se poco manutenibile e pratico.
Tuttavia nella maggior parte delle situazioni in cui si verifica la necessità di
produrre una stampa, devono essere utilizzate delle strutture per
organizzare i dati che superano la banale tabella. È in questi frangenti che
è possibile apprezzare un reporting tool in tutta la sua capacità espressiva
e potenza.
In generale i report vengono classificati in tre categorie: i report di tipo
columnar, di tipo tabular ed di tipo cross table (o semplicemente crosstab).
Fig.2.5: Columnar report
Reporting tool in ambiente Open Source - Pagina 20 di 84
I primi due rappresentano il caso di stampa più comune. Talvolta, se i dati
da stampare sono molti, si usa raggruppare i record mediante “gruppi” per
meglio esporre le informazioni. La caratteristica principale di questi tipi di
Fig.2.6: Tabular report
report è la staticità di alcuni elementi base come le etichette o il numero di
colonne.
Fig.2.7: Crosstab report
Reporting tool in ambiente Open Source - Pagina 21 di 84
I crosstab report, invece, hanno un numero di colonne che può variare a
seconda dei dati stampati. Nessuno degli strumenti di reportistica open
source supporta questo tipo di report che introduce un notevole grado di
complessita nel codice di generazione e nella descrizione del layout. Solo
l’autore di JasperReports ha annunciato un futuro timido supporto per i
crosstab report, proponendo la possibilità di definire in maniera dinamica i
campi che formano le colonne. Nel caso sia possibile fissare un upper
bound al numero di colonne necessarie nel crosstab report, è possibile
“simulare” questo tipo di report mediante un tabular report costruendo
opportunamente il set di record che andrà ad alimentare la stampa.
2.6 Alcune note su performance e produttività
Tutti i reporting tool utilizzano una logica di esecuzione molto simile:
tramite un meccanismo di design (visuale o meno), viene generato un
prodotto intermedio (nel caso di JasperReports addirittura il codice di una
classe java) che viene compilato e serializzato su file. Questo permette al
generatore della stampa di minimizzare le risorse in termini di lettura e
parsing del layout della stampa. Un certo overhead si ha nel caso di
formule interpretate e non compilate direttamente. Tuttavia l’esportazione
risulta, nella maggior parte dei casi, il tallone d’achille dei prodotti di
reportistica, richiedendo grandi risorse in termini di memoria (in particolare
nel caso di report contenenti molte righe) e di potenza di calcolo (tra i più
diffusi, il pdf è decisamente il formato che necessita il maggior numero di
risorse. Tuttavia difficilmente un report interamente programmato “a mano”
supererà in maniera netta le performance di un buon motore di
reportistica. Al contrario, per quel che riguarda la produttività, gli strumenti
visuali permettono un’imparagonabile abbattimento dei tempi di sviluppo.
Le prime versioni di iReport, ancora allo stato embrionale e privo di tutte le
funzionalità che possiede oggi, permetteva, secondo le stime di un utente
americano, di incrementare di 30 volte la velocità di creazione dei report
precedentemente sviluppati scrivendo a mano il codice XML con il quale
vengono definite le stampe di JasperReports.
Reporting tool in ambiente Open Source - Pagina 22 di 84
2.7 Linguaggi di programmazione e reporting tool
A questo punto della trattazione, il lettore si sarà reso conto quanto il
linguaggio java faccia la parte del leone nel campo della reportistica. In
realtà esistono numerosissime librerie per creare documenti nei formati più
diffusi (pdf, html, XML, ecc…) per linguaggi diversi da java, ma non sono
reporting tool, bensì API per poter generare in maniera semplice e veloce
documenti nei formati citati.
In ambiente open source tutti gli strumenti di repostistica più diffusi sono
scritti in java. Esiste, inoltre, un software di reportistica sviluppato
dall’Apache Group chiamato Cocoon, il cui funzionamento è interamente
basato su XML e i fogli di trasformazione XSLT tramite i quali il documento
XML iniziale viene convertito in diversi formati tra cui pdf e xls. Da una
parte Cocoon rappresenta probabilmente il reporting tool più evoluto al
mondo dal punto di vista delle tecnologie utilizzate, ma il suo utilizzo è
apparentemente così complesso e macchinoso, o per lo meno così
distante dai canonici processi di creazione di un report tramite
un’interfaccia visuale, che ho deciso di non trattarlo in questa tesi.
Reporting tool in ambiente Open Source - Pagina 23 di 84
3. JasperReports
Nato nel settembre del 2001 per opera del rumeno Teodor Daciu,
JasperReports rappresenta un valido strumento di reportistica in ambiente
open source. Oltre che per le notevoli funzionalità e semplicità d’uso, deve
la sua popolarità al noto servlet engine Tomcat, che ha inserito questa
libreria all’interno della propria distribuzione. È da oltre un anno uno dei
più attivi progetti presenti su Source Forge, ed alla data odierna (ottobre
2003) ha raggiunto la versione 0.5.0.
Rispetto a software analoghi presenti nel panorama open source,
JasperReports spicca per la sua architettura basata sull’idea di modularità
ed estensibilità. Esiste la possibilità, in “jasper”, di personalizzare qualsiasi
fase del ciclo di vita del report, dalla compilazione all’esportazione, alla
gestione dei dati da stampare. L’integrazione con qualsiasi tipo di
applicativo java è estremamente semplice e la dotazione di elementi
grafici è sufficiente a soddisfare la maggior parte dei requisiti necessari a
creare le stampe più complesse. Il punto di forza, oltre alla facilità di
implementazione delle fonti di dati, è la possibilità di utilizzare sottoreport
ricorsivi con i quali è possibile generare report con dettaglio costituito
virtualmente da un numero illimitato di pagine per ogni singolo record. Si
pensi ad esempio ad una stampa molto complessa nella quale si vuole
definire contenuti differenti per le prime pagine, inserendo, ad esempio
una pagina per il titolo, una per il sommario comprensivo di numeri di
pagina, ed una serie di tabelle relative ad informazioni eterogenee, Con
JasperReports (ed un po’ di esperienza) è possibile creare stampe di
questo tipo, che vanno anche molto oltre il semplice layout visto nel
capitolo precedente.
Reporting tool in ambiente Open Source - Pagina 24 di 84
La libreria include funzionalità di esportazione per i formati pdf, xsl, html,
xml e csv, oltre che una serie di classi per l’anteprima e la stampa diretta.
Sfortunatamente non esiste ancora un “driver” per esportare i report in
formato rtf. La spiegazione di questa carenza è dovuta alla complessità di
scrivere un generatore rtf secondo i canoni con cui sono scritti gli altri
“driver”: questi sono tutti basati sul concetto di griglia nella quale vengono
inseriti tutti gli elementi che costituiscono il report. In rtf non esiste
un’organizzazione degli elementi basata su una griglia (come, invece,
accade per pdf, xsl, html, ecc…), e ciò complica notevolmente le cose. Si
noti che tecnicamente non c’è nessun impedimento nello scrivere una
classe per esportare un documento jasper in rtf, ma evidentemente la
mancanza non è percepita come tale dalla nutrita comunità di utenti.
Per l’esportazione in pdf e xsl, JasperReports si appoggi a due famose
librerie open source: iText e POI. Di iText abbiamo già parlato nel capitolo
introduttivo, POI, invece, è un progetto dell’Apache Group, ed è una
libreria java creata per la generazione di file Excel in formato biff (meglio
conosciuto con la sua extensione XLS).
Una seconda carenza di rilievo è l’assenza di una fonte dati XML. In realtà
tale tipo di fonte dati esiste, ma è presente come patch al programma e
soffre di notevoli limitazioni.
Per quel che riguarda la definizione dei report, JasperReports si affida
completamente ad una propria sintassi XML con la quale è possibile
descrivere interamente il layout della stampa da creare. Inizialmente
l’autore Teodor Danciu annunciò l’intenzione di scrivere un tool aggiuntivo
per poter creare visualmente le stampe. Con la nascita di altri strumenti
con lo stesso fine, questo task venne completamente abbandonato.
Rimangono comunque, all’interno della libreria, delle funzionalità per poter
visualizzare a video il layout di una stampa come definita mediante l’XML.
Il diretto “concorrente“ di JasperReports è un progetto chiamato
JFreeReport, ospitato come il primo su Source Forge. Personalmente
ritengo JasperReports un prodotto molto più maturo e costruito secondo
un’architettura decisamente più flessibile (oltre ad essere decisamente più
utilizzato).
Su
un
blog
visibile
Reporting tool in ambiente Open Source - Pagina 25 di 84
all’indirizzo
http://roller.anthonyeden.com/page/chenihsu ho trovato per caso un
articolo molto ben scritto relativo al confronto tra i due sistemi di
reportistica.
L’autore dichiara esplicitamente di essere alla ricerca di un reporting tool
open source per il proprio progetto e di aver tra tutti selezionato
JasperReports e JFreeReport
quali possibili candidati. Questa prima
selezione sembra essere basata su una serie di parametri molto semplici
quali diffusione, popolarità, qualità della documentazione disponibile sul
sito di ciascun progetto, ecc…
Segue una più approfondita analisi dei due sistemi di stampa dalla quale
si evince come JasperReports sia la soluzione vincente in tutte le scelte
implementative.
3.1 Funzionamento di JasperReports
Come tutti i software di reportistica, JasperReports è costituito
logicamente da tre componenti: uno per la compilazione del layout, uno
per
la generazione della stampa ed uno per l’esportazione (a volte
chiamato anche rendering) del documento.
Essendo sprovvisto di uno strumento visuale per la creazione del layout
(lacuna che può essere facilmente colmata utilizzando uno dei diversi
strumenti sviluppati da terze parti), la definizione del report viene effettuata
mediante un documento XML. Questo documento segue la sintassi
definita in un apposito DTD e permette di definire la dimensione delle
bande, i gruppi, gli elementi e la loro posizione specifica, nonché altre
informazioni quali un query SQL da eseguire per popolare la stampa, o le
formule da utilizzare per calcolare campi speciali. Scrivere codice XML per
definire una stampa, dopo aver preso un po’ di confidenza con la specifica
sintassi (per altro molto semplice ed intuitiva), è tutt’altro che complesso o
addirittura paragonabile alla difficoltà di stesura di una pagina HTML
dotata di un po’ di javascript. Grazie all’uso di nomi immediatamente
comprensibili come rectangle o textfield è facile orientarsi nonostante
l’elevato numero di tag.
Reporting tool in ambiente Open Source - Pagina 26 di 84
Il
report
così
sviluppato
viene
processato
mediante
il
JasperCompileManager. Questa classe trasforma l’XML opportunamente
validato in un file sorgente java che verrà compilato e successivamente
serializzato in un file con estensione jasper. La fase di compilazione viene
effettuata solo una volta (esattamente come avviene per i normali
programmi java). Il codice compilato risulterà, in fase di esecuzione della
stampa, particolarmente performante. Qualora sia necessario mediante il
proprio programma creare dinamicamente il sorgente del report, questo
deve necessariamente essere compilato prima di essere eseguito per
dare vita alla stampa. Poiché la compilazione del report assume la
presenza di un compilatore, che potrebbe non essere presente in un
ambiente di produzione, JasperReports permette di utilizzare come
compilatore in alternativa a quello standard di java, un pacchetto chiamato
BeanShell (http://www.beanshell.org), in grado di eseguire codice java
interpretato! Per la verità JasperReports fa molto di più, mettendo a
disposizione un’interfaccia chiamata JRCompiler per poter utilizzare
compilatori personalizzati.
Ad ogni modo la fase di compilazione produce sempre un file jasper. Da
questo file è possibile creare una stampa grazie al JasperFillManager,
che si occuperà di popolare con i dati il nostro report.
I dati che il JasperFillManager utilizzarà per la stampa possono essere
passati secondo due paradigmi completamente differenti. Il più semplice
(e limitativo) è quello di delegare alla libreria il compito di recuperare i dati
leggendoli mediante una query SQL precedentemente associata al report.
L’unico
compito
dell’applicazione
sarà
quello
di
passare
al
JasperFillManager un oggetto Connection opportunamente inizializzato
(ovvero già collegato al database sul quale la query verrà effettuata).
Il secondo paradigma, invece, è quello che utilizza un’opportuna struttura
dati
che
implementa
l’interfaccia
JRDataSource.
Parleremo
estensivamente di questa interfaccia e di come essa rappresenti uno dei
punti di forza di JasperReports in seguito. Per ora diciamo soltanto che è
una sorta di enumeratore di righe (o records) dotato di un metodo
(getField) per accedere ai campi del record corrente.
Reporting tool in ambiente Open Source - Pagina 27 di 84
Ciò che viene generato dal JasperFillManager è una classe chiamata con
molta fantasia JasperPrint. Questa può essere salvata su file in formato
XML (secondo una sintassi definita da JasperReports) riutilizzabile in
seguito nel caso si voglia per esempio posticipare l’esportazione in un
formato più diffuso, oppure richiamare una delle classi dedicate
all’esportazione che estendono l’interfaccia JRExporter. Nelle prime
versioni della libreria, l’esportazione era gestita da una classe chiamata
JasperExportManager; fortunatamente questa prima soluzione è stata
abbandonata (anche se il JasperExportManager esiste ancora per
retrocompatibilità), ed è stato introdotto il modello a “driver” di stampa,
costituito appunto dall’interfaccia JRExporter. Attualmente è possibile
esportare un report creato con JasperReports nei formati: PDF, HTML,
XLS, CSV e XML. Come spiegato all’inizio del capitolo, JasperReports è
privo di un exporter per il formato RTF, ma come si intuisce si tratta “solo”
di estendere opportunamente l’interfaccia JRExporter…
La libreria contiene poi una serie di classi per il design e la visualizzazione
Fig. 3.1: Esempio di anteprima mediante JasperReports
a video della stampa come anteprima. Queste funzionalità vengono
utilizzate da normali programmi java che utilizzano le swing o all’interno di
Reporting tool in ambiente Open Source - Pagina 28 di 84
un browser mediante un applet. In figura 3.1 è possibile vedere come si
presenta l’anteprima gestita da JasperReport ed integrata in un
programma java basato su swing.
Fig.3.2: Funzionamento di JasperReports
In figura 3.2 e 3.3 è schematizzano il funzionamento completo della
libreria. Riassumendo, la definizione del report XML passa attraverso un
compilatore che valida il report e genera una versione compilata dello
stesso. Mediante il JasperFillManager la stampa viene popolata con i dati
provenienti da una connessione JDBC o da una datasource per produrre
un documento eventualmente da esportare in uno dei formati supportati.
Fig.3.3: Contesti di utilizzo
I possibili contesti di utilizzo della libreria sono veramente vari. Essendo
scritto in 100% puro java, JasperReports può essere impiegato in
qualsiasi applicazione basata sulla piattaforma J2EE comprese le
applicazioni Web. Tramite semplici bridge software, è possibile poi
Reporting tool in ambiente Open Source - Pagina 29 di 84
utilizzare JasperReports anche in altri contesti, ad esempio in applicazioni
basate su PHP o altri linguaggi di scripting lato server.
3.2 Struttura del report secondo jasper ed elementi
grafici
JasperReports gestisce ben otto bande predefinite e infinite bande di
raggruppamento, costituite da un header ed un footer rispettivamente
sopra e sotto la banda di detail.
Oltre alle bande (che descriveremo in dettaglio tra poco), JasperReports è
Fig.3.4: Bande predefinite in JasperReports
in grado di dividere la banda di dettaglio e quelle di raggruppamento in
colonne (da 1 a n), in modo da poter sfruttare al meglio lo spazio
disponibile sulla pagina. È bene non confondere il concetto di colonna
appena espresso con quello della colonna che si forma in seguito
Reporting tool in ambiente Open Source - Pagina 30 di 84
all’allineamento di campi stampati uno sotto l’altro. La figura 11 evidenzia
la differenza tra i due concetti di colonna ed esemplifica l’uso ottimizzato
della banda di dettaglio (nel caso specifico spezzato in due colonne).
Fig.3.5: Differenza tra una colonna del dettaglio e una colonna di dati
In generale, in JasperReports esistono delle regole che determinano
l’altezza massima di una banda, mentre la larghezza è sempre uguale alla
Reporting tool in ambiente Open Source - Pagina 31 di 84
larghezza della pagina meno i margini laterali. L’altezza di una banda può
essere impostata esplicitamente in fase di design (specificando un valore
di altezza contenuto nell’intervallo consentito per la specifica banda),
tuttavia la reale altezza assunta dalla banda in fase di stampa può variare
a seconda del suo contenuto. È il caso in cui all’interno di un dettaglio
inseriamo un sottoreport contenente qualche centinaio di righe: il dettaglio
risulterà alto addirittura diverse pagine. Tramite un attributo chiamato
isSplitAllowed, l’utente può abilitare o meno la possibilità di stampare una
banda su più pagine qualora la cosa si renda necessaria. Infine tramite
un’espressione booleana è possibile rendere una banda invisibile.
Velocemente descriviamo l’utilizzo delle bande principali (nell’ordine in cui
vengono tipicamente inserite nel codice XML).
Background Questa banda comparve per la prima volta nella versione
0.4.6 di JasperReports e fu introdotta dopo insistenti richieste da
parte di diversi utenti per poter creare watermark ed effetti simili
(come ad esempio una cornice attorno a tutta la pagina). Può
assumere un’altezza massima pari alla dimensione del report.
Title Il nome di questa banda rende chiaro il suo utilizzo. Tuttavia gli usi
che se ne fanno non si limitano a quelli di spazio in cui inserire
banalmente un titolo. Grazie ad una speciale opzione, è possibile
forzare la stampa di questa banda su una pagina separata. Con un
po’ di astuzia, questa possibilità può essere sfruttata mediante dei
sottoreport per simulare un salto pagina. Per quel che riguarda le
dimensioni ammesse, non è possibile superare a tempo di design
l’altezza del report (margini superiore ed inferiore esclusi). Tuttavia
JasperReports in fase di validazione controlla che l’altezza di tutte
le bande (background escluso) sia inferiore o uguale all’altezza del
report. Nel caso il titolo sia impostato per essere stampato su una
nuova pagina, la limitazione rimane costringendo l’utente ad
utilizzare sottoreport per sfruttare un’intera pagina per il titolo, che
altrimenti consumerebbe tutta
l’altezza disponibile per le altre
bande producendo un errore di validazione.
Reporting tool in ambiente Open Source - Pagina 32 di 84
Page header Questa sezione permette di definire l’intestazione di pagina.
L’altezza definita in fase di design solitamente non cambia durante
il processo di generazione (salvo l’inserimento di componenti
ridimensionabili come campi testo dinamici o sottoreport). Il page
Fig.3.6: Page header
header compare in tutte le pagina della stampa nella stessa
posizione definita in fase di design.
Column header È una banda tipica di JasperReports. Viene stampata
all’inizio di ogni colonna di dettaglio. Questo permette di
Fig.3.7: Column header
visualizzare ad esempio le etichette delle colonne del report ad ogni
cambio pagina. In altri strumenti di reportistica le etichette delle
colonne vengono inserite in un group header, perdendo il vantaggio
della ristampa automatica delle intestazioni nei salti pagina o di
colonna.
Reporting tool in ambiente Open Source - Pagina 33 di 84
Group header Un report può contenere zero o più bande di
raggruppamento, ovvero sezioni che permettono di dividere in veri
Fig.3.8: Group header
e propri gruppi i record del dettaglio. Un group header è sempre
accompagnato da un group footer ( entrambi possono essere
indipendentemente visibili o meno). Al gruppo sono associati diversi
parametri che ne determinano il comportamento dal punto di vista
grafico; è possibile imporre la stampa di un group header sempre in
una nuova pagina o in una nuova colonna, forzarne la stampa su
tutte le pagine (come un page header, ma a livello di gruppo),
fissare un’altezza superata la quale la banda del gruppo debba
essere
stampata
in
una
nuova
facciata.
L’espressione
di
raggruppamento può essere rappresentata da un qualsiasi
frammento di codice java che restituisca una stringa. La stringa
stessa
rappresenterà
il
valore
di
raggruppamento.
Questo
meccanismo svincola il concetto di raggruppamento “per campi”
tipico di molti sistemi di reportistica ed estremamente limitativo. La
caratteristica dei gruppi di spezzare il dettaglio viene spesso
utilizzata
per
ottimizzare
(o
forse
dovremmo
dire
“gestire
correttamente”) la stampa di dettagli suddivisi in più pagine o
contenenti molti sottoreport.
Reporting tool in ambiente Open Source - Pagina 34 di 84
Detail Ad ogni record letto dalla fonte dati che alimenta la stampa,
corrisponde una banda di dettaglio. Con ogni probabilità, la maggior
parte degli elementi della stampa verranno posizionati qui.
Group footer È la banda che corrisponde al group header, e solitamente
contiene campi in cui visualizzare subtotali o elementi grafici di
separazione come linee, ecc…
Column footer È una banda di comodo che appare alla fine di ogni
colonna. La sua dimensione non è in nessun modo modificabile
(nemmeno qualora contenesse elementi ridimensionabili come
suttoreport o campi testo con un numero di righe variabile).
Page footer È il piè di pagina. Compare in tutte le pagine e come il
column footer non è ridimensionabile.
Summary Questa sezione è quella che in altri sistemi viene chiamato
Report footer. Permette di inserire campi relativi a calcoli totali,
medie, o quant’altro si voglia inserire alla fine del nostro report.
Quando il report viene generato utilizzando una fonte dati vuota, è
possibile impostare uno dei tre possibili comportamenti di JasperReports:
visualizzare una pagina vuota, non produrre nessuna pagina, visualizzare
tutti gli elementi ad eccezione di quelli inseriti nelle bande di dettaglio
(groupHeader, detail, groupFooter). Quest’ultima modalità permette di
stampare il titolo anche se la stampa non ha record. Si noti che esistono
diversi modi di passare dati da stampare a JasperReports (ad esempio
usando i parametri), e quindi è possibile senza fonte dati creare un report
solo utilizzando la banda del titolo.
Gli elementi grafici utilizzabili in una stampa creata con JasperReports
sono sette: la linea, il rettangolo, l’ellisse, l’immagine, il testo statico, il
campo di testo (simile al testo statico, ma in grado di visualizzare stringhe
prodotte mediante un’espressione) e il sottoreport.
Reporting tool in ambiente Open Source - Pagina 35 di 84
Un elemento deve essere sempre associato ad una banda. La posizione è
definita mediante coordinate x,y. Poiché l’altezza delle bande in generale
può cambiare, la coordinata y viene interpretata come valore relativo
rispetto alla banda. Le opzioni di valutazione di y sono tre:
floating position Significa che l’elemento può essere spinto verso il basso
in seguito al ridimensionamento di elementi precedenti;
Fixed position relative to the top of the parent band Significa che
indipendentemente dalla dimensione della banda, l’elemento deve sempre
stare a y punti sotto l’inizio della sezione;
Fixed position relative to the bottom of the parent band Significa che
indipendentemente dalla dimensione della banda, l’elemento deve sempre
stare a y punti sopra la fine della sezione.
Non ci soffermeremo sui dettagli di ogni singolo elemento. È utile tuttavia
spiegare il concetto di evaluationTime (associato ai campi di testo ed agli
elementi immagine). L’evaluationTime (istante di valutazione), si riferisce a
quando una specifica espressione debba essere valutata. Infatti il risultato
della valutazione di un espressione può cambiare durante la generazione
della stampa (si pensi ad esempio all’espressione che rappresenta il
numero di pagina: all’inizio della stampa tale espressione assumerà valore
uno e crescerà durante la creazione delle pagine successive). Gli
evaluationTime possibili sono i seguenti:
Now
È il valore predefinito. Significa che l’espressione deve essere
valutata nell’istante in cui viene incontrata;
Report Questo evaluationTime viene usato quanto si vuole posticipare la
valutazione di un’espressione al completamento di un report;
Page
La valutazione viene posticipata al completamento della pagina;
Column La valutazione viene posticipata al completamento della colonna;
Group
La valutazione viene posticipata al completamento del gruppo
specificato assieme a questo evaluationTime;
Reporting tool in ambiente Open Source - Pagina 36 di 84
Questo meccanismo della valutazione posticipata è decisamente utile in
moltissime situazioni, la più diffusa delle quali è forse quella in cui è
necessario stampare il numero di pagina corrente e quello totale (es.
pagina x di n). La soluzione consiste nel creare due campi di testo, il primo
con un espressione del tipo:
“Pagina “ + $V{PAGE_NUMBER} + “di “
e tempo di valutazione “now”, il secondo, affiancato, con un’espressione
simile
“ “ + $V{PAGE_NUMBER}
ma tempo di valutazione “report”.
Il risultato finale sarà qualcosa di simile a…
Pagina 3 di 24
Abbiamo appena visto i primi due piccoli esempi di espressioni. Ne
parleremo tra poco, ma si può già notare come esse siano simili al
linguaggio java con qualche piccola nuova accortezza sintattica.
3.3 Campi, variabili, parametri ed espressioni
Ogni strumento di reportistica definisce un meccanismo per collegare i
campi di un dataset (o di una struttura paragonabile, utilizzata come fonte
dati) ai i campi del report. Solitamente questo binding è implicito ed è
puramente basato sui nomi delle colonne presenti nel dataset.
JasperReports
impone
che
i
campi
della
fonte
dati
vengano
preventivamente dichiarati mediante la sintassi XML definita in questo
frammento di DTD:
<!ELEMENT field (fieldDescription?)>
<!ATTLIST field
name NMTOKEN #REQUIRED
class (java.lang.Object | java.lang.Boolean | java.lang.Byte
java.util.Date
|
java.sql.Timestamp
|
java.sql.Time
java.lang.Double
|
java.lang.Float
|
java.lang.Integer
java.io.InputStream
|
java.lang.Long
|
java.lang.Short
java.math.BigDecimal | java.lang.String) "java.lang.String"
Reporting tool in ambiente Open Source - Pagina 37 di 84
|
|
|
|
>
<!ELEMENT fieldDescription (#PCDATA)>
Ecco un esempio di dichiarazione dei campi di una query SQL:
<queryString><![CDATA[select * from CLIENTI]]></queryString>
<field name="COGNOME1" class="java.lang.String"/>
<field name="NOME" class="java.lang.String"/>
<field name="SESSO" class="java.lang.String"/>
<field name="PROVINCIA" class="java.lang.String"/>
<field name="TEL1" class="java.lang.String"/>
<field name="TEL2" class="java.lang.String"/>
L’elemento queryString non è obbligatorio, come non è necessario
interrogare un database relazionale per generare una stampa con
JasperReports, ma lo abbiamo volutamente inserito per esplicitare il fatto
che i campi dichiarati in questa porzione di codice verranno recuperati
mediante la query specificata.
La necessità di dover dichiarare i nomi e i tipi dei campi, letti dalla fonte
dati, ci da un’idea di come il linguaggio usato da JasperReports per le
espressioni (nelle quali questi campi verranno utilizzati) sia fortemente
tipizzato: si tratta infatti del linguaggio java (arricchito di qualche nuovo
dettaglio sintattico).
In maniera molto simile ai campi della data source, vengono dichiarate le
variabili ed i parametri. Le variabili vengono utilizzate per effettuare i
calcoli all’interno del report (come totali, subtotali, medie, ecc…).
I parametri, invece, costituiscono una via parallela alla fonte dati per
passare sotto forma di oggetti java informazioni dal programma chiamante
al report.
Le espressioni sono frammenti di codice java il cui risultato è sempre un
oggetto. Un esempio di espressione booleana (utilizzabile nei campi che
determinano se stampare o meno un elemento o una banda) è la
seguente:
new Boolean(true)
L’espressione in se non è molto utile in quanto produce esattamente
l’effetto di default (stampa sempre l’elemento), ma si noti come il risultato
non sia il valore primitivo true, ma un oggetto Boolean.
Reporting tool in ambiente Open Source - Pagina 38 di 84
Il tipo di ritorno delle espressioni è determinato dal contesto. Per quel che
riguarda i campi di testo, i cui valori sono sempre determinati da
un’espressione, è necessario specificarne il tipo tramite uno specifico
attributo, (che quindi determinerà il tipo di ritorno dell’espressione).
Per utilizzare nelle espressioni i campi della fonte dati, le variabili e i
parametri, si utilizza la sintassi $F{Nome campo}, $V{Nome variabile} e
$P{Nome parametro}. È necessario ricordare che questi sono sempre
oggetti e mai tipi primitivi. Questo significa che se dobbiamo sommare due
campi di tipo Integer e ritornarne il valore, l’espressione da usare sarà del
tipo:
new Integer( $F{Campo_intero_1}.intValue() +
$F{Campo_intero_2}.intValue() )
Non essendoci in java l’overload degli operatori, è necessario, nella
somma, estrapolare i valori primitivi dagli oggetti (in questo caso Integer)
con la funzione intValue(), quindi sommarli e restituire nuovamente un
oggetto Integer. Il tutto è un po’ macchinoso, ma con un minimo di nozioni
di java si supera facilmente ogni ostacolo e se ne apprezza la potenza,
essendo ammesso qualsiasi costrutto java. Qualora, infatti, si volesse
implementare una forma di validazione dei dati, o calcoli particolari, è
sufficiente scrivere una classe java dotata di un metodo statico per
raggiungere velocemente il nostro obiettivo ed usare un’espressione del
tipo….
MyClass.myMethod( $F{MyField})
L’esempio mostra come sia possibile operare sul campo MyField in
qualsiasi modo utilizzando java.
3.4 L’interfaccia JRDataSource
I dati da stampare possono essere ottenuti da diverse fonti come un
database o un documento XML. Questi dati vengono presentati a
JasperReports sempre sotto forma di uno speciale set di record
utilizzando un’apposita interfaccia chiamata JRDataSource.
Reporting tool in ambiente Open Source - Pagina 39 di 84
JasperReports viene distribuito con un diverse implementazioni di questa
interfaccia pronte all’uso e in grado di “wrappare” ResultSet JDBC,
TableModel (java swing), Collection di oggetti java, Array e Vector di
oggetti, ecc… JasperReports, inoltre, è in grado di generare una stampa
attingendo i dati senza l’ausilio di una classe JRDataSource, ma
semplicemente utilizzando una query SQL opportunamente associata al
report
ed
eseguita
mediante
una
connessione
JDBC
procurata
dall’applicazione che necessita la stampa.
L’intrfaccia JRDataSource è veramente semplice.
public interface JRDataSource
{
public boolean next() throws JRException;
public Object getFieldValue(JRField jrField) throws JRException;
}
Come si vede, richiede l’implementazione di soli due metodi:next() e
getFieldValue(), che prende come argomento un oggetto di tipo JRField.
Anche ques’ultima classe (in realtà una nuova interfaccia) è veramente
semplice:
public interface JRField
{
public String getName();
public String getDescription();
public void setDescription(String description);
public Class getValueClass();
}
Di fatto l’uso di tale interfaccia si riduce ad un meccanismo semplice per
associare il tipo di ritorno atteso al nome del campo richiesto.
L’interfaccia JRDataSource permette, dunque, di enumerare dei record,
costituiti da una serie di campi a cui è associato un nome ed un tipo. Nel
caso più banale una JRDataSource potrebbe essere rappresentata da un
Vector i cui record sono gli oggetti del vettore costituiti da un’unica
colonna di tipo Object. Il valore del campo è l’oggetto memorizzato alla
posizione corrente (ovvero la riga ottenuta mediante la chiamata a next()).
Nel caso in cui venga raggiunta la fine del set di record, la chiamata a next
restituisce il valore booleano false.
Reporting tool in ambiente Open Source - Pagina 40 di 84
La somiglianza di questa interfaccia con quella di un ResultSet java, ci
permette
di
capire
perché
l’implementazione
della
classe
JRResultSetDataSource si riduca ad una sorta di convertitore di tipi SQL
in tipi java. Eccone il codice (la parte in grigio evidenzia il codice relativo
alla selezione della corretta classe java di presentazione del dato rispetto
al tipo SQL posseduto)…
public class JRResultSetDataSource implements JRDataSource
{
private ResultSet resultSet = null;
public JRResultSetDataSource(ResultSet rs)
{
resultSet = rs;
}
public boolean next() throws JRException
{
boolean hasNext = false;
if (resultSet != null) {
try {
hasNext = resultSet.next();
}
catch (SQLException e) {
throw new JRException("Unable to get next
record.", e);
}
}
return hasNext;
}
public Object getFieldValue(JRField field) throws JRException
{
Object objValue = null;
if (field != null && resultSet != null) {
Class clazz = field.getValueClass();
try {
if (clazz.equals(java.lang.Object.class))
{
objValue =
resultSet.getObject(field.getName());
}
else if
(clazz.equals(java.lang.Boolean.class)) {
objValue =
new Boolean( resultSet.getBoolean(field.getName()) );
}
else if
(clazz.equals(java.lang.Byte.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull()) {
objValue = null;
} else {
objValue = new
Byte((String)objValue);
}
}
else if
(clazz.equals(java.util.Date.class)) {
objValue =
resultSet.getDate(field.getName());
if(resultSet.wasNull()) {
objValue = null;
}
}
else if
(clazz.equals(java.sql.Timestamp.class)) {
objValue =
resultSet.getTimestamp(field.getName());
Reporting tool in ambiente Open Source - Pagina 41 di 84
if(resultSet.wasNull()) {
objValue = null;
}
}
else if
(clazz.equals(java.sql.Time.class))
{
objValue =
resultSet.getTime(field.getName());
if(resultSet.wasNull())
objValue = null;
}
}
else if
(clazz.equals(java.lang.Double.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull())
objValue = null;
} else {
objValue = new
Double((String)objValue);
}
}
else if
(clazz.equals(java.lang.Float.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull())
objValue = null;
} else {
objValue = new
Float((String)objValue);
}
}
else if
(clazz.equals(java.lang.Integer.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull())
objValue = null;
} else {
objValue = new
Integer((String)objValue);
}
}
else if
(clazz.equals(java.io.InputStream.class)) {
objValue =
resultSet.getBinaryStream(field.getName());
if(resultSet.wasNull())
objValue = null;
}
}
else if
(clazz.equals(java.lang.Long.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull())
objValue = null;
} else {
objValue = new
Long((String)objValue);
}
}
else if
(clazz.equals(java.lang.Short.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull())
objValue = null;
} else {
objValue = new
Short((String)objValue);
}
}
else if
(clazz.equals(java.math.BigDecimal.class)) {
objValue =
Reporting tool in ambiente Open Source - Pagina 42 di 84
{
{
{
{
{
{
{
resultSet.getString(field.getName());
if(resultSet.wasNull()) {
objValue = null;
} else {
objValue =
new BigDecimal((String)objValue);
}
}
else if
(clazz.equals(java.lang.String.class)) {
objValue =
resultSet.getString(field.getName());
if(resultSet.wasNull()) {
objValue = null;
}
}
}
catch (Exception e)
{
throw new JRException(
"Unable to get value for field '" +
field.getName() + "' of class '" +
clazz.getName() + "'", e);
}
}
return objValue;
}
}
3.5 Integrare JasperReports in un progamma java
Per concludere questo capitolo su JasperReports, analizziamo il codice
necessario ad integrare un programma java con le funzionalità di stampa
offerte da JasperReports.
3.5.1 Compilazione di un report
Come precedentemente spiegato, una volta scritto il file XML che
definisce la stampa, è necessario compilarlo per creare un file jasper.
Il codice necessario ad effettuare questa operazione è il seguente:
String xmlFileName = “test.xml”;
String jasperFileName = “test.jasper”;
try {
JasperCompileManager.compileReportToFile(
xmlFileName,
jasperFileName);
} catch (JRException jrex)
{
}
Nuovamente ci troviamo di fronte a codice veramente banale. Il nostro file
xml (nell’esempio “test.xml”) viene caricato dal CompilerManager,
Reporting tool in ambiente Open Source - Pagina 43 di 84
convertito in un file sorgente java e serializzato in un file jasper
(nell’esempio “test.jasper”). È tuttavia possibile controllare tutti i passi di
questo processo impostando diverse proprietà di sistema, tra le quali
ricordiamo:
jasper.reports.compile.temp La directory in cui creare il file java
temporaneo;
jasper.reports.compile.keep.java.file Per evitare che il file java generato
venga cancellato ad operazione conclusa
jasper.reports.compiler.class Per specificare la classe di tipo JRCompiler
da utilizzare per la compilazione
È inoltre possibile abilitare o meno la validazione XML del file sorgente ed
impostare un classpath personalizzato in fase di compilazione.
Il risultato finale sarà comunque sempre un file jasper.
Si noti che i file compilati non sono compatibili tra le diverse versioni di
JasperReports. Questa scelta ha permesso a JasperReports di svincolarsi
dalle complicazioni necessarie al mantenimento di una compatibilità, a
livello di binario, verso il basso, ma ha tuttavia spiazzato in molte
occasioni gli utenti, costretti a ricompilare le stampe ad ogni upgrade. La
compatibilità rimane comunque a livello di codice XML (sempre verso il
basso, ma non sempre verso l’alto, nel senso che in alcune versioni sono
stati aggiunti alcuni tag non riconosciuti dalle versioni precedenti).
3.5.2 Esempio di creazione di una JRResultSetDataSource
Come esempio di creazione di una fonte dati, abbiamo utilizzato una delle
più comuni e semplici da utilizzare: la JRResultSetDataSource,
che
permette di “wrappare” un resultset java ottenuto mediante una query
SQL.
Class.forName( jdbDriver );
Connection conn = DriverManager.getConnection(
jdbcUrl,
jdbcUser,
jdbcPassword);
Statement stmt = conn.createStatement();
ResultSet rs = stmt.executeQuery(query);
Reporting tool in ambiente Open Source - Pagina 44 di 84
JRDataSource jrds = new JRResultSetDataSource(rs);
La semplicità di utilizzo è veramente estrema e non varia molto con altri
tipi di JRDataSource. Infatti, il compito più difficile risulta essere
l’eventuale sviluppo della fonte dati, ma come già visto, in generale
JasperReports è in grado di sopperire alla maggior parte delle esigenze
mediante le JRDataSource predefinite.
3.5.3 Generazione della stampa
Per la generazione della stampa, sono necessarie due cose: il file jasper e
una fonte dati (ovvero un oggetto di tipo JRDataSource o una
connessione JDBC aperta verso un database). Quello che produrremo
sarà un’istanza dell’oggetto Print, una struttura dati intermedia utilizzata da
JasperReports che ci servirà per esportare la stampa in un qualche
formato specifico, piuttosto che visualizzarla a video.
java.util.HashMap map = new java.util.HashMap();
map.put("MyParam",new Integer( 100 ) );
String jasperFile = "myreport.jasper";
dori.jasper.engine.JasperPrint print=null;
dori.jasper.engine.JasperReport report = d
ori.jasper.engine.JasperManager.loadReport(
cl.getResourceAsStream(jasperFile));
print = dori.jasper.engine.JasperFillManager.fillReport(
report ,
map,
new JREmptyDataSource());
Questa volta il codice è stato un po’ arricchito per evidenziare alcune altre
possibilità messe a disposizione della libreria. Nella prima riga viene
instaziata una HashMap, per passare al motore che genera la stampa un
insieme di coppie nome/oggetto: i parametri.
Questa volta abbiamo
deciso di caricare autonomamente il file jasper. Il risultato è una nuova
istanza della classe JasperReport, mediante la quale è possibile accedere
a tutta la struttura del report. È possibile, mediante questo oggetto,
effettuare al volo piccole modifiche alla stampa senza la necessità di
modificare sorgenti e di ricompilarli. Il metodo chiave è fillReport della
Reporting tool in ambiente Open Source - Pagina 45 di 84
classe JasperFillManager. Come datasource abbiamo utilizzato la
sorgente dati nulla: JREmptyDataSource(), utile in moltissime situazioni.
3.5.4 Visualizzazione di una stampa a video
Siamo arrivati così al punto di voler visualizzare la stampa a video. Per
farlo utilizzeremo il nostro oggetto Print in questo modo:
dori.jasper.view.JasperViewer.viewReport( print );
L’effetto sarà quello di veder aprirsi a video un finestra con l’anteprima
della nostra stampa.
3.5.5 Esportazione di una stampa in un file
Infine, presentiamo un esempio di codice relativo all’esportazione delle
stampe in formati standard come pdf e html.
dori.jasper.engine.JRExporter exporter =
new dori.jasper.engine.export.JRPdfExporter();
String pdfFileName = “myreport.pdf”;
exporter.setParameter(
dori.jasper.engine.JRExporterParameter.OUTPUT_FILE_NAME,
pdfFileName);
exporter.setParameter(
dori.jasper.engine.JRExporterParameter.JASPER_PRINT,print);
exporter.exportReport();
Come si può notare, per esportare una stampa in un determinato formato,
è necessario appoggiarsi ad un “driver” o (nel gergo di JasperReports) ad
un exporter specifico. Le direttive di esportazione vengono impostate
come parametri sulla classe exporter (nel codice presentato viene
impostato il nome del file pdf da creare e viene passato l’oggetto print che
dovrà essere trasformato in pdf).
Ogni exporter può definire un proprio insieme di nomi di parametri o
appoggiarsi (come in questo caso) alle costanti definite nella classe
JRExporterParameter.
Reporting tool in ambiente Open Source - Pagina 46 di 84
Addentrarci oltre nelle funzionalità e capacità di JasperReports esula dagli
scopi di questa tesi. Tuttavia, molti degli argomenti trattavi in questo
capitolo verranno ripresi nel capitolo successivo, nel quale parleremo di
iReport, in buona sostanza un programma che facilita la maggior parte dei
processi di sviluppo per JasperReports visti fino a questo momento.
Reporting tool in ambiente Open Source - Pagina 47 di 84
4. iReport
iReport nacque ufficialmente il 9 ottobre 2002, quando venne registrato
come progetto sul sito Sourceforge.net, la culla della maggior parte dei
programmi open source oggi disponibile.
In realtà lo sviluppo vero e proprio iniziò circa qualche mese prima. Allora
stavo lavorando ad un software web-oriented basato su servlet Java. Il
committente aveva espresso insistentemente l’esigenza di un numero
sostanzioso di report adatti alla stampa. Le pagine web, infatti, hanno
spesso la caratteristica di non rendere le informazioni stampate su carta
chiare e leggibili quanto quelle visualizzare a video.
Ritenemmo il pdf il formato ideale per produrre i report e iniziai a cercare
delle librerie che potessero facilitarmi il lavoro. Finii, come capita a
chiunque cerchi con un motore di ricerca le parole chiave “pdf” e “java”,
sul sito di iText, la più autorevole libreria java open source per la
produzione di documenti pdf. Una ricerca più approfondita permise di
evidenziare altri software che facevano al caso mio: si trattava di tre
strumenti di reportistica java open source: i già citati DataVision,
JasperReports e JFreeReport.
Così, dopo una rapido test dei tre strumenti di reportistica, decisi di
adottare JasperReports quale motore per le stampe.
L’impatto iniziale, in realtà, non fu dei migliori a causa di una
documentazione
appena
sufficiente
a
capire
i
meccanismi
di
funzionamento della libreria (carenza a cui Teodor Danciu, l’autore di
JasperReports, rimediò presto con la pubblicazione on line di un manuale
dai contenuti essenziali, ma espressi in modo chiaro e diretto, e venduto
ad un prezzo più che accettabile). Non furono di grande aiuto nemmeno
Reporting tool in ambiente Open Source - Pagina 48 di 84
gli strumenti allora disponibili per la creazione visuale delle stampe, anche
se gli sforzi fatti da Jackie Manning, autore di JasperDesign, ed Eric
Swenson con JasperEdit ed OpenReports, hanno contribuito in maniera
determinante alla diffusione di JasperReports (spingendo anche me ad
adottare questa libreria).
Così decisi di scrivere iReport, ispirandomi allo stesso JasperDesign.
Inizialmente iReport doveva essere utilizzato solo internamente alla
società presso cui stavo lavorando. Fu così che decisi di svilupparlo
usando Microsoft Visual J++. Questa scelta accese una sorta di guerra di
religione quando iReport fu reso pubblico. In realtà la velocità con cui è
possibile produrre un programma scritto con il suddetto defunto ambiente
Microsoft è tuttora incomparabile a qualsiasi altro sistema di sviluppo (a
mio modestissimo avviso). La riprova di questo fu lo stesso iReport,
realizzato in versione 0.0.1 in meno di un mese di lavoro a tempo perso!
(La versione java sviluppata successivamente ha richiesto un impegno
decisamente superiore in termini di ore di lavoro.) La scelta, inoltre, era
dettata da questioni prestazionali. Le WFC (Windows Fondation Classes),
ovvero le classi java offerte da Microsoft per utilizzare la GUI nativa di
Windows (ed in generale tutte le API win32), offrivano prestazioni
incredibilmente superiori rispetto ai lenti ed esosi, in termini di memoria,
componenti swing.
Oggi la mia opinione si è appiattita alla media: fu una scelta scellerata.
Tuttavia senza quella scelta, credo che iReport oggi non sarebbe quello
che è. Infatti, pur destando diffidenza tra gli utenti di JasperReports, iniziò
a guadagnarsi in poco tempo il titolo di miglior editor visuale per i file
jasper. Un utente di iReport, Nathan W. Phelps espose così il suo punto di
vista:
"Let me (a random person) jump in here. While I do think that using J++ is
a bit odd, I've been looking for a native Win32 Jasper designer. I have
tried JasperEdit, JasperDesigner and the one for Eclipse all unsatisfactory.
My company has a "no Java on the client side" policy as well. So the fact
that this thing is in J++ could help me out. I just downloaded the source
and ran it through the Visual Studio .NET J# upgrade wizard which ran
Reporting tool in ambiente Open Source - Pagina 49 di 84
into very few problems. In other words, with a bit of work I can get this
thing running on pure .NET using J#. That is pretty cool, and just may get
me where I need to go!"
[Predi me (una persona a caso). Pur ritenendo che il J++ sia un po’
superato, stavo cercando un designer per Jasper. Ho provato JasperEdit,
JasperDesign e quello per Eclipse rimanendo insoddisfatto. La mia società
segue una politica del tipo “no Java sulla parte client”. Così il fatto che
questa cosa (iReport n.d.t.) sia in J++ potrebbe aiutarmi. Io ho solo
scaricato i sorgenti e fatti girare con l’upgrade del Visual Studio .NET J#,
che produce pochissimi problemi di compilazione. In altre parole con un
po’ di lavoro, si potrebbe far girare questa cosa sotto .NET usando J#. È
veramente forte e mi porta nella direzione in cui voglio andare!]
Ho rilasciato ben dieci versioni di iReport per win32: dalla 0.0.1 alla 0.1.0,
quest’ultima rilasciata il 19 aprile del 2003, riscuotendo un buon successo:
complessivamente oltre 13.000 download ad oggi, settembre 2003.
Il
5
maggio
postai
un
messaggio
sul
forum
di
JasperReports
provocatoriamente intitolato: iReport goes to 100% pure java!
Al
messaggio
seguirono
diverse
risposte
di
entusiasmo
ed
incoraggiamento. Una versione java di iReport era quello che tutti gli utenti
si aspettavano; iReport aveva guadagnato sufficiente popolarità da
rendere il salto di qualità obbligatorio. Iniziai così il porting non senza
difficoltà. Cercai di riutilizzare quanto più codice fosse possibile, ma in
realtà il vecchio codice Visual J++ era veramente orribile e tutte le routine
grafiche avevano prestazioni assai poco confortanti quando adattate al
supporto per la grafica di java. Tuttavia il 14 giugno vide la luce la prima
versione interamente scritta in java: la 0.2.0, praticamente inutilizzabile (se
comparata alla versione 0.1.0 per win32). L’ultima versione ad oggi, la
0.2.2, ha portato quasi a parità in merito a funzionalità la versione per
win32 (non più supportata) e la versione java. Ma la strada da compiere è
ancora lunga per arrivare ad una versione stabile.
Tuttavia già oggi iReport rappresenta una valida alternativa a sistemi di
reportistica commerciali; la scelta è dettata in particolare da motivazioni
Reporting tool in ambiente Open Source - Pagina 50 di 84
economiche, dato l’elevato costo delle alternative commerciali, spesso
vincolate da macchinose licenze basate su numero di client e volumi di
stampa.
La popolarità di iReport è molto cresciuta con la nascita della versione
java. Sfortunatamente durante il periodo esatto di uscita della versione
0.2.0 (per l’appunto la prima versione java di iReport) nel giugno 2003, le
Pagine viste e num. di download
(fonte SourceForge.net)
N. di download/pagine viste
16000
14000
12000
10000
8000
6000
4000
2000
Oc
t
No obe
ve r 20
De mb 02
ce er 2
m 00
b
Ja er 2 2
nu 00
Fe ary 2
br 20
ua 03
ry
M 20
ar 03
ch
2
Ap 003
ril
2
M 003
ay
2
Ju 003
ne
2
Ju 003
A ly
Se ugu 200
pte st 3
m 200
be 3
r2
00
3
0
Mesi (da ottobre 2002 a settembre 2003)
Fig. 4.1: Statistiche progetto iReport (fonte SourceForge.net)
statistiche relative al download di SourceForge erano fuori uso (si noti la
linea rosa dei download nel grafico in figura 4.1 in corrispondenza del
mese di giugno). Tuttavia il numero di contatti avuti sulle pagine web del
sito del progetto indicato un interesse esploso proprio nello stesso
periodo.
Reporting tool in ambiente Open Source - Pagina 51 di 84
Sempre relativamente al sito del progetto sono disponibili anche le
statistiche registrate mediante un servizio gratuito chiamato CQ Counter.
Accessi al sito ireport.sf.net
(fonte CQ Counter)
12000
Numero di contatti
10000
8000
6000
4000
2000
Ap
ril
20
03
Ju
ne
20
03
Au
gu
st
20
03
Oc
tob
er
20
02
De
ce
m
be
r2
00
2
Fe
br
ua
ry
20
03
0
Mesi (da ottobre 2002 a settembre 2003)
Fig. 4.2: Statistiche progetto iReport (fonte CQ Counter)
Si noti che i dati di CQCounter si riferiscono alla sola home page del sito
http://ireport.sf.net.
Ad oggi (settembre 2003) il numero di download ha superato le 20.000
unità destinate ad aumentare velocemente.
Per quel che riguarda le statistiche relative al Sistema Operativo utilizzato,
allo stato attuale le informazioni ricavate dall’accesso al sito dicono che il
76,10% degli utenti utilizza Windows 2000/XP, seguito da Linux (8,83%),
Win 98 (6,18%), Win NT (5,91%), Mac OSX (1,11%) . Il resto degli utenti
utilizzano sistemi quali SunOS, FreeBSD, AIX, ecc…
È chiaro che il bacino di utenza accumulato nei mesi in cui iReport era
disponibile solo per win32 è ancora quello più numeroso, ma sicuramente
destinato ad diminuire percentualmente rispetto all’utenza Linux.
Reporting tool in ambiente Open Source - Pagina 52 di 84
Curiose, infine, sono le statistiche relative alla lingua del browser utilizzato
per collegarsi al sito di iReport: queste cifre danno un’idea di quanto
iReport sia diffuso.
Lingua
Contatti web
English
32409
Portuguese
3247
Italian
3176
French
2959
Spanish
2877
Japanese
876
Korean
773
Polish
723
Thai
570
Dutch
526
Russian
473
German
454
Swedish
385
Hungarian
268
Danish
259
Croatian
188
Turkish
178
Finnish
163
Bulgarian
142
Norwegian
142
Greek
125
Slovak
101
Czech
95
Slovenian
75
Icelandic
63
other/unknown
58
Indonesian
52
Hebrew
48
Romanian
46
Estonian
42
Ukrainian
40
Arabic
28
Serbian
26
Interlingue
19
Reporting tool in ambiente Open Source - Pagina 53 di 84
Catalan
17
Lithuanian
17
Malay
17
Hindi
15
Afrikaans
15
Latvian Lettish
12
Persian
10
Macedonian
7
Basque
4
Galician
3
Byelorussian (Belarussian) 2
Telugu
2
Georgian
1
Serbo-Croatian
1
L’8 aprile un utente coreano di nome Yumi Kim scrive questo messaggio
sul forum di iReport:
iReportPlus, Newly developed web reporting solution, was released.
This solution is developed based on JasperReports and iReport that
are well-known open-source web reporting solutions.
Anybody who want to make web based reports easily and rapidly
is able to use this solution as a freeware for non-commercial use.
iReportPlus made by iMobile Technology Inc. has some advanced
features as follows :
- Report Designer with Wizards
- Report Export as Jasper, Excel and PDF
- Database Explorer
- Server Explorer & Preview
- Local Data Explorer
iReportPlus also provides many functions other than those listed above.
You can get more detailed information and download it from
http://www.ireportplus.com/
For technical support, please feel free to contact us.
L’ingenuità del messaggio ha dell’incredibile. Il software citato nel
messaggio, iReportPlus, è in realtà iReport con qualche piccola modifica
estetica ed integrato in un sistema più ampio per la pubblicazione dei
report utilizzando un database Oracle. Ironica la frase “anybody […] is
able to use this solution as a freeware for non-commercial use”. C’è da
Reporting tool in ambiente Open Source - Pagina 54 di 84
chiedersi quanti, per scopi non commerciali, necessitino di un sistema
distribuito di reportistica basato su Oracle…
Passano poche ore e la comunità di iReport si scaglia contro la società
coreana con messaggi di condanna contro l’evidente violazione della
licenza GPL con cui iReport è distribuito. La violazione viene segnalata
alla Free Software Fondation che mi suggerisce di tentare di risolvere la
cosa cercando di spiegare la gravità dell’accaduto alla società coreana
mediante un’e-mail dai toni contenuti. Il messaggio sortisce solo in parte
gli effetti desiderati, strappando la promessa di un tempestivo rilascio di
iReportPlus sotto i termini della licenza GPL. Nessun successivo rilascio di
iReportPlus (tanto meno in licenza GPL) vedrà mai la luce (tuttavia il sito
di iReportPlus è tuttora attivo).
Fortunatamente esistono al mondo società commerciali in grado di capire
la sottile differenza presente tra il termine free ed il termine open source.
Ma soprattutto in grado di sfruttare le altissime potenzialità offerte dal
software open source in genere. A tale proposito vorrei aprire una piccola
parentesi. Non so per quale paradossale ragione, il denaro ricevuto
inaspettatamente (o quello vinto) è più apprezzato di quello guadagnato.
Forse perché il primo viene ottenuto senza un vero sforzo apparente che
ne controbilanci il valore stesso. Questo è il motivo per il quale un
software open source non solo è gratis entro i termini della licenza d’uso
con cui è distribuito, ma spesso e volentieri il suo prezzo è estremamente
conveniente (dal punto di vista economico) al di fuori di tali termini: infatti
qualsiasi offerta inaspettata proposta ad un programmatore per ottenere
una licenza non GPL del suo software OpenSource verrà ben considerata,
e la trattazione del prezzo sarà mediamente breve e vantaggiosa per
entrambe le parti, sempre.
Una società milanese, Tecnes Milano, mi chiese di fargli un’offerta per
completare in breve tempo la gestione dei font in iReport, modifiche che
sarebbero state rilasciate sotto licenza GPL e i cui diritti sarebbero rimasti
comunque miei. In pratica l’offerta era una sorta di incentivo allo sviluppo
di funzionalità a cui Tecnes era interessata. Le funzionalità in questione
furono rilasciate dopo meno di 48 ore, lasciando Tecnes stupita per due
ragioni: in primo luogo per il brevissimo tempo intercorso tra la richiesta di
Reporting tool in ambiente Open Source - Pagina 55 di 84
un offerta e lo sviluppo delle funzionalità richieste (inaspettata da un
programma privo di supporto esplicito, ma soprattutto ineguagliabile da un
qualsiasi tipo di supporto commerciale), dall’altra dall’esiguo costo del
lavoro (tipico quando lo sviluppo viene realizzato per passione e non solo
per denaro).
Prima di completare questa lunga introduzione ad iReport, non posso non
citare Mark Rhodes di Sydran Services, LLC., che senza avanzare alcuna
richiesta specifica, ma solo a titolo di ringraziamento per l’opera svolta (e
per i soldi fatti risparmiare alla propria società con l’adozione di iReport e
JasperReports quale sistema di reportistica), mi fece una gradita
donazione quale incentivo allo sviluppo dell’allora primitivo, ma già
promettente, iReport.
4.1 iReport e JasperReports
iReport non rappresenta da solo una soluzione di reportistica, si tratta
piuttosto di uno strumento molto evoluto per lo sviluppo, il test e
l’esportazione di report creati ed utilizzabili mediante la libreria
JasperReports.
Grazie alla grande quantità di funzionalità di iReport, come la possibilità di
Fig.4.3: Integrazione di JasperReports con iReport
Reporting tool in ambiente Open Source - Pagina 56 di 84
collegarsi a database relazionali mediante JDBC, e la capacità di generare
ed esportare autonomamente i report, questo programma può essere
utilizzato, oltre che come strumento di sviluppo, anche come strumento di
reportistica standalone.
IReport è in grado di leggere report definiti mediante XML e file compilati
in formato jasper. Questi documenti possono essere modificati e risalvati
in XML o compilati a sua volta in file jasper. Grazie ad un evoluto sistema
di gestione degli errori di compilazione, iReport facilita molto la vita allo
sviluppatore che non dovrà scorrere centinaia di righe di codice XML per
correggere i propri errori, ma sarà sufficiente un colpo di mouse per
posizionarsi direttamente sull’espressione o il campo che ha generato
l’errore.
IReport supporta tutti i tag XML definiti da JasperReports ad eccezione
dell’elementGroup, un particolare tag per controllare il ridimensionamento
di alcuni elementi rispetto ad altri.
4.2 L’interfaccia principale
L’interfaccia di iReport si è evoluta molto nel passaggio tra la versione
0.1.0 e la versione 0.2.0, scritta in puro java utilizzando swing. La finestra
principale è suddivisa in quattro parti: la barra dei menu con la toolbar in
alto, l’area di navigazione a destra, l’area di lavoro con le finestre dei
documenti al centro e la console per la visualizzazione dei messaggi in
basso.
La gestione delle finestre interne ricalca quella tipica dei programmi
Windows, con la possibilità di sfruttare al massimo l’area dell’MDI
container (caratteristica non nativa dell’interfaccia swing).
Lo strumento di navigazione è utilizzato sia per visualizzare l’elenco dei
documenti attualmente aperti, con l’indicazione mediante un’opportuna
icona dello stato del documento (salvato o “sporco”, cioè potenzialmente
modificato1), sia per visualizzare la struttura ad albero degli elementi che
1
Attualmente IReport (versione 0.2.2) non è ancora in grado di determinare se un
documento sia stato o meno modificato, non essendo tenuta traccia di tutte le possibili
modifiche apportabili al documento.
Reporting tool in ambiente Open Source - Pagina 57 di 84
compongono il report (figura 4.5). Mediante questi strumenti è possibile
portare in primo piano il documento da modificare o selezionare in
Fig.4.4: Interfaccia principale di iReport
Fig.4.5: Struttura del documento
maniera rapida uno o più elementi del documento corrente.
Reporting tool in ambiente Open Source - Pagina 58 di 84
Le caratteristiche di un nuovo documento (menu File->New document),
vengono richieste mediante un’apposita finestra di dialogo (figura 4.6).
Fig.4.6: Proprietà del report
È possibile specificare le dimensioni della stampa, l’orientamento del
foglio, i margini e molte altre informazioni esposte in dettaglio nella tabella
seguente.
Report name
Nome interno della stampa
Preset sizes
Questa combobox permette di selezionare dimensioni di
documento predefinite
Width e Height Larghezza e altezza della pagina. Le misure possono
essere espresse in divere unità di misura (compreso il
pixel con risoluzione fissa a 75dpi)
Orientation
Orientamento della pagina
Page margin
In
questa
scheda
vengono
specificati
i
margini
superiore, inferiore e laterali.
Columns
In questa scheda viene specificato il numero di colonne
in cui dividere la pagina per visualizzare il dettaglio, la
larghezza della singola colonna e la loro distanza.
Scriptlet
In
questa
scheda
viene
specificato
il
nome
dell’eventuale classe scriptlet da utilizzare con il report.
La classe deve estendere la classe JRAbstractScriptlet
Reporting tool in ambiente Open Source - Pagina 59 di 84
e permette di definire codice java da eseguire
all’occorrenza di diversi eventi durante la generazione
della stampa quali il cambio di gruppo, il cambio di
pagina, il passaggio al successivo record di dettaglio,
ecc…
More…
In questa scheda è possibile definire se la banda del
titolo e la banda del sommario debbano essere
stampate su una pagina a parte, l’ordine in cui stampare
i record (verticale o orizzontale nel caso si abbia più di
una
colonna
di
dettaglio
a
disposizione),
il
comportamento del report in caso di assenza di dati e
l’encoding del file XML (di default UTF8).
Appena creato, il nuovo documento si presenta come un foglio bianco
diviso nelle sette bande principali di JasperReports.
A questo punto è possibile iniziare a lavorare sulla nostra stampa
aggiungendo gli elementi, modificando le bande, impostando formule ed
espressioni.
4.3 Bande ed elementi
Il report vuoto crea le sette bande principali di JasperReports impostate ad
un’altezza predefinita compresa tra 30 e 100 pixel. Selezionando il menu
View->Bands è possibile accedere alla finestra di gestione della bande
Fig.4.7: Gestione delle bande del report
Reporting tool in ambiente Open Source - Pagina 60 di 84
(figura 4.7), mediante la quale potremo definirne le caratteristiche di ogni
singola sezione: l’altezza esatta (in pixel), la possibilità di spezzare la
banda in fase di stampa (Split allowed) e l’espressione booleana che ne
determini la visibilità (se l’espressione è nulla, la banda sarà sempre
visibile). L’altezza delle bande è inoltre modificabile visualmente
trascinando le linee di demarcazione delle stesse. La stessa operazione di
trascinamento effettuata tenendo premuto il tasto SHIFT permette di agire
sul margine superiore della banda più bassa rispetto alla linea di
demarcazione, dando la possibilità di “scoprire” bande di altezza nulla.
Per inserire gli elementi nelle bande è necessario selezionare uno dei
seguenti strumenti posti sulla toolbar e descrivere un rettangolo nella
banda desiderata.
Linea
Rettangolo
Rettangolo con angoli arrotondati
Ellisse
Immagine
Testo statico
Campo di testo (definito con un’espressione)
Sottoreport
Grafico (non ancora implementato nell’attuale versione 0.2.2)
L’elemento appena creato viene associato alla banda nella quale si trova il
vertice superiore sinistro. Sarà possibile modificare la banda di
appartenenza
dell’elemento
mediante
la
finestra
delle
proprietà
dell’elemento. È possibile richiamare tale finestra con un doppio click
sull’elemento (o gli elementi) da modificare, o selezionando il menu File>Element Properties. Le caratteristiche degli elementi possono essere
raggruppate secondo la gerarchia in figura 4.8, che rispecchia la gerarchia
delle classi java che implementano gli elementi.
Reporting tool in ambiente Open Source - Pagina 61 di 84
Elemento
Elemento grafico
Rettangolo
Linea
Immagine
Grafico
Elemento di testo
Testo statico
Campo di testo
Sottoreport
Fig. 4.8: Gerarchia degli elementi grafici gestiti da iReport
La finestra delle proprietà degli elementi è organizzata a schede, e ad
ognuno dei rettangoli presenti in figura 4.8 corrisponde una scheda.
La scheda Common visualizza le caratteristiche comuni a tutti gli
Fig.4.9: Scheda “Common”
elementi, ovvero:
Band: la banda a cui l’elemento è associato;
Top: posizione verticale rispetto alla base superiore della banda;
Left: posizione orizzontale rispetto il lato sinistro della banda;
Reporting tool in ambiente Open Source - Pagina 62 di 84
Width: larghezza dell’elemento;
Height: altezza dell’elemento;
Foreground: colore primario; nel caso di elementi grafici è il colore con il
quale viene disegnata la cornice, mentre nel caso di elementi testuali è il
colore usato per il testo;
Background: colore di riempimento dell’elemento; ha effetto solo se la
proprietà transaparent è disattivata;
Transparent: se attivata, rende lo sfondo dell’oggetto trasparente;
Remove line when blank: questa proprietà permette di eliminare una
porzione di documento qualora nessun oggetto debba essere stampato
nella fascia orizzontale che include questo oggetto (qualora l’elemento
non debba essere stampato);
Print in first whole band: questa proprietà forza la stampa dell’elemento
nella prima banda stampata in una nuova pagina (o su una nuova
colonna); solitamente si usa quando è stata disabilitata la stampa di valori
ripetuti, ma si vuole ripetere il valore su pagine (o colonne) nuove;
Print when detail overflows: permette di ristampare un elemento su una
nuova pagina (o colonna) qualora la banda a cui appartiene non è stata
interamente stampata nella precedente pagina (o colonna).
Print repeated values: permette di abilitare o meno la stampa di valori
ripetuti del campo;
Position type: permette di definire il tipo di posizione dell’elemento
rispetto alle variazioni di altezza della banda; le possibili opzioni sono:
Float: impone all’elemento di slittare verso il basso se “spinto” da altri
elementi che lo precedono;
FixRelativeToTop: impone che l’elemento venga stampato sempre
alla stessa altezza rispetto alla base superiore della banda;
FixRelativeToBottom: impone che l’elemento venga stampato
sempre alla stessa altezza rispetto alla base inferiore della
banda;
Print When Group Changes: questa opzione permette di stampare
l’oggetto qualora cambi il valore dell’espressione associata al gruppo
specificato;
Reporting tool in ambiente Open Source - Pagina 63 di 84
Print When Expression: tramite questa proprietà è possibile impostare
un’espressione booleana che determinerà la visibilità dell’elemento; il
valore predefinito, nel caso non venga inserita nessuna espressione, è
true;
Fig.4.10: Scheda “Graphics Element”
Gli elementi grafici (scheda Graphics Element) integrano le proprietà
comuni con altre tre caratteristiche:
Pen: è lo spessore del bordo disegnato attorno all’elemento;
StretchType: è il tipo di deformazione che l’elemento subisce in base alla
posizione di altri oggetti o alla variazione dell’altezza della banda; i
possibili valori sono:
NoStretch: nessun tipo di deformazione
RelativeToTallestObject: la deformazione è basata sull’oggetto più vicino
(si usa, ad esempio, quando si vuole incorniciare un altro elemento di
dimensione variabile come un campo di testo, mediante un rettangolo)
RelativeToBandHeight: la deformazione è proporzionale all’altezza della
banda (usato ad esempio quando si usano delle linee come separatori di
colonna);
Fill: è il tipo di riempimento da eseguire qualora l’elemento non sia
trasparente; attualmente l’unico valore ammesso è Solid.
La
scheda
Line
permette
di
definire
la
direzione
della
linea
(LineDirection) che può assere di tipo TopDown (\) o BottomUp (/). Le
coordinate della linea sono ricavate dalla posizione e dalla dimensione
dell’elemento, sufficienti a descrivere anche l’elemento rettangolo. Unica
Reporting tool in ambiente Open Source - Pagina 64 di 84
Fig.4.11: Scheda “Line”
Fig.4.12: Scheda “Rectangle”
caratteristica aggiuntiva di quest’ultimo (scheda Rectangle) è il raggio di
curvatura degli angoli qualora li si vuole arrotondati (il Radius).
Fig.4.13: Scheda “Image”
La scheda Image completa la serie degli elementi grafici.
Image Expression: è un’espressione che ritorna il tipo definito in Image
Expression Class; se il tipo è String, l’espressione viene trattata come un
nome di file; mediante il pulsante “Find…” è possibile caricare un file
immagine e produrre l’espressione che ne rappresenta il percorso;
Image Expression Class: è la classe di ritorno dell’espressione;
Scale Image: definisce come l’immagine debba adattarsi al riquadro nella
quale è contenuta; i possibili valori sono:
Clip: l’immagine viene tagliata se più piccola dell’elemento nel quale è
contenuta;
FillFrame: adatta l’immagine alle dimensione dell’elemento
Reporting tool in ambiente Open Source - Pagina 65 di 84
RetainShape:
adatta
l’immagine
alle
dimensioni
dell’elemento
mantenendo le proporzioni originali;
Using Cache: se selezionato, JasperReports manterrà in memoria
l’immagine durante la generazione della stampa evitando di ricaricarla
ogni volta venga richiesto;
Vertical Alignment: permette di specificare l’allineamento verticale
dell’immagine rispetto al rettangolo definito dall’elemento; i possibili valori
sono: Left,Center e Right;
Horizontal Alignment: permette di specificare l’allineamento orizzontale
dell’immagine rispetto al rettangolo definito dall’elemento; i possibili valori
sono: Top, Middle e Bottom;
Evaluation Time: il concetto di evaluation time è stato spiegato nel
capitolo su JasperReports; rappresenta il tempo al quale deve essere
valutata un’espressione (in questo caso l’Image Expression); i possibili
valori sono sempre:
Now la valutazione dell’espressione è immediata;
Report:
la
valutazione
dell’espressione
viene
posticipata
al
raggiungimento dell’ultimo record;
Page: la valutazione dell’espressione viene posticipata al successivo
cambio di pagina;
Column: la valutazione dell’espressione viene posticipata al successivo
cambio di colonna;
Group: la valutazione dell’espressione viene posticipata al successivo
cambio del valore dell’espressione associata al gruppo definito nella
proprietà Evaluation Group.
Reporting tool in ambiente Open Source - Pagina 66 di 84
Tutti i campi di testo possiedono le caratteristiche visualizzate nella
scheda Font:
Fig.4.14: Scheda “Font”
Fig.4.15: Scheda “Static Text”
Report Font: è il riferimento alla definizione di un font a livello di report;
Font Name: è il nome di un font di sistema (o java); la combobox
visualizza la lista dei font disponibili sulla particolare macchina;
Size: è la dimensione del carattere;
PDF Font Name: qualora si intenda stampare i report in PDF, mediante
questo campo è possibile specificare un font PDF predefinito o
selezionare la voce “External TTF Font” per specificare un font di tipo TTF;
TrueType Font: permette di selezionare un font TTF da utilizzare per la
stampa del campo in PDF;
Bold, italic, underline, Strike Trough: definiscono l’aspetto del font;
Line Spacing: l’interlinea da usare per il testo (Single, 1_1_2 o Double);
Horizontal Align: permette di definire l’allineamento orizzontale del testo,
che potrà essere Left, Center, Right e Justified.
Vertical Align: permette di definire l’allineamento verticale del testo, che
potrà essere Top, Middle e Bottom;
PDF Embedded specifica se il font usato debba essere incorporato nel
file pdf;
PDF Encoding: specifica il set di caratteri da utilizzare per interpretare la
stringa da stampare;
Reporting tool in ambiente Open Source - Pagina 67 di 84
Oltre a queste caratteristiche, il campo di testo statico ha un’unica
proprietà aggiuntiva: il testo da stampare. Si noti che in questo caso il
testo non è rappresentato da un’espressione java, ma da una semplice
stringa di testo.
Fig.4.16: Scheda “TextField”
I campi di testo dinamici oltre ai già citati Expression Class, Evaluation
Time ed Evaluation Group, possiedono le proprietà:
StretchWithOverflow: permette la crescita verticale del campo in caso di
necessità (come testi molto lunghi);
Blank When Null: permette di non stampare il campo se il risultato
dell’espressione è null;
Pattern: è un metodo molto utile mediante il quale è possibile formattare
numeri
e
date
con
espressioni
del
tipo
“€#,###,###.00”
(es.
€1.234.567,00) o del tipo “dd/MM/yyyy” (es. 10/12/2003).
Textfield Expression: l’espressione che determina il valore del campo;
Fig.4.17: Scheda “Subreport 1”
Fig.4.18: Scheda “Subreport 2”
Reporting tool in ambiente Open Source - Pagina 68 di 84
deve ritornare il tipo specificato in Textfield Expression Class;
Le schede relative al sottoreport sono due.
Parameter Map Expression: rappresenta un espressione utilizzabile per
indicare una classe di tipo Map contenente parametri da passare al
sottoreport.
Connection/Datasource Expression: mediante questa combobox è
possibile selezionare il criterio di collegamento del report master al
sottoreport: il collegamento può avvenire tramite il passaggio di una
connessione JDBC aperta (ad esempio quella passata al report master
dal programma chiamante e memorizzata nel parametro predefinito
$P{REPORT_CONNECTION}), oppure tramite il passaggio di una
JRDataSource o ancora si puo non voler esprimere nessun tipo di
collegamento;
Subreport Expression: specifica il nome del sottoreport o un’istanza della
classe JasperReport (in accordo con il valore specificato in Subreport
Expression Class);
Subreport Parameters: è possibile creare una serie di parametri da
passare al sottoreport e valorizzabili in maniera dinamica mediante
normali espressioni java (un uso classico è il passaggio del codice del
record padre da utilizzare per il recupero di record correlati da stampare
nel sottoreport);
Esiste, infine, una scheda speciale chiamata Hyper Link utilizzabile per i
Fig.4.19: Scheda “Hyper Link”
Reporting tool in ambiente Open Source - Pagina 69 di 84
campi di testo e le immagini, mediante la quale è possibile specificare dei
link ipertestuali (da utilizzare nei documenti pdf).
Anchor Name Expression: attribuisce all’elemento corrente un nome da
utilizzare come link per eventuali collegamenti;
Hyperlink Type: definisce il tipo di link:
None: nessun tipo;
Reference: riferimento ad un URL esterno (ad esempio una pagina web);
LocalAnchor: riferimento ad un link interno al documento;
LocalPage:riferimento ad un numero di pagina del documento corrente;
RemoteAnchor: riferimento ad un link in un documento pdf esterno;
RemotePage: riferimento ad una pagina di un documento pdf esterno;
L’uso dei campi Hyperlink Reference Expression, Hyperlink Anchor
Expression e Hyperlink Page Expression è condizionato dalla scelta
del tipo di link. In generale Hyperlink Reference Expression contiene
sempre il riferimento al file a cui puntare per soddisfare il link.
Attualmente è in fase di sviluppo l’elemento “Chart”, che sfrutta l’elemento
immagine. In figura è visibile l’interfaccia sperimentale per la gestione
delle proprietà del grafico.
Fig.4.20: Scheda “Chart”
4.4 Definizione di una fonte dati
Come già discusso nel capitolo relativo a JasperReports, i dati da
stampare possono essere letti in diversi modi e da sorgenti eterogenee
quali database, file XML, file di testo formattato, ecc…
Reporting tool in ambiente Open Source - Pagina 70 di 84
IReport supporta qualsiasi tipo si connessione JDBC e quattro tipi di
datasource (in grado di gestire qualsiasi altro tipo di sorgente
personalizzata).
4.4.1 Empty data source (JREmptyDataSource)
Si tratta di una speciale fonte dati che di fatto non contiene nessun record.
Può essere utilizzata in diverse situazioni per produrre report non basati in
generale su recordset.
4.4.2 XML Data source
Questa datasource è in fase di sviluppo e dovrebbe permettere di
alimentare una stampa a partire dai contenuti in un documento XML.
Fig.4.21: Definizione di una data source per file XML
I parametri richiesti da questo tipo di sorgente dati sono semplicemente il
nome da assegnare a questa sorgente, ed il nome del file XML.
4.4.3 JavaBean Set Datasource
Anche questa datasource, come la precedente, è ancora in fase di
sviluppo. L’idea è quella di gestire un insieme di oggetti JavaBean che
vengono
generati
dall’utente
mediante
una
classe
java
scritta
appositamente. L’insieme può essere costituito da una Collection o un
Array di JavaBean. La classe che deve essere realizzata a supporto di
questa datasource, viene chiamata “factory” e dovrebbe contenere un
metodo statico chiamando il quale viene prodotto l’Array o la Collection.
Reporting tool in ambiente Open Source - Pagina 71 di 84
I parametri richiesti da questo tipo di sorgente dati sono: il nome da
Fig.4.22: Definizione di una JavaBean Set data source
assegnare alla sorgente, il nome della classe factory, il metodo statico da
invocare su tale classe, ed il tipo di ritorno del metodo specificato.
4.4.4 Custom Datasource
Questo tipo si datasource è completamente generico. IReport non
conosce come sia implementata la specifica fonte dati, ma delega la
creazione della datasource ad una classe esterna, sviluppata dall’utente e
dotata di un metodo statico che ritorna un oggetto JRDataSource.
I parametri richiesti da questo tipo di sorgente dati sono il solito nome da
Fig.4.23: Definizione di una Custom data source
assegnare alla sorgente, il nome della classe factory ed il metodo statico
da invocare su tale classe (che ritornerà un’istanza della JRDataSource
da utilizzare per la generazione della stampa). È previsto lo sviluppo di un
meccanismo per poter definire nella finestra di configurazione della
custom data source una serie di parametri da passare al metodo di
Reporting tool in ambiente Open Source - Pagina 72 di 84
creazione della JRDataSource. In questo modo sarà facile implementare
nuove sorgenti parametrizzabili e utilizzabili mediante iReport.
4.4.5 Impostazione di una connessione JDBC
È possibile eseguire query SQL per la selezione di dati su un database
relazionale usando una connessione JDBC. L’impostazione avviene
mediante
il
gestore
di
connessioni
(menu
Datasources-
>Connection/Datasources). Premendo il pulsante “New” apparirà la
Fig.4.24: Definizione di una fonte dati JDBC
finestra in figura 4.24. È necessario assicurarsi che il driver JDBC
specificato si trovi nel classpath. A questo proposito si noti che iReport
non gestisce, per il momento, classpath dinamici, è quindi opportuno
assicurarsi che le classi o il jar del driver siano caricati dallo script di avvio
di iReport.
Premendo il pulsante “Wizard” è possibile ottenere un suggerimento sulla
specifica sintassi del driver JDBC. Premere “Test” per controllare che la
connessione sia stata impostata correttamente. “Save” per salvarla.
Per utilizzare la connessione appena creata, selezionare il menu build>Set active connection e selezionare la sorgente dati desiderata
dall’elenco delle sorgenti configurate. IReport memorizzerà la scelta che
verrà riproposta anche ai successivi riavvii.
Reporting tool in ambiente Open Source - Pagina 73 di 84
4.5 Recupero dei campi mediante SQL
iReport è dotato di un comodo strumento per recuperare i nomi ed i tipi dei
campi SQL selezionati da una query e registrarli all’interno del report per
poterli utilizzare. L’operazione avviene mediante la stessa finestra nella
quale viene definita la query. Per accedervi selezionare il menu view>Report Query. Una volta digitata la query di selezione, è sufficiente
premere il pulsante “Read fields” per ottenere i nomi dei campi e relativi
Fig.4.25: Recupero dei campi di una query
tipi.
A questo punto, selezioneremo i campi da “registrare” nel nostro report e
premeremo il pulsante “Register fields to report”. Per associare al report la
query visualizzata, dovremo premere il pulsante “Save query to report”.
Possiamo in qualsiasi momento gestire i nostri campi selezionando il
menu View->Report fields. Mediante questa operazione verrà visualizzata
la finestra per l’aggiunta, la modifica e l’eliminazione dei campi, del tutto
simile a quella che vedremo nel prossimo paragrafo per gestire variabili e
parametri.
Reporting tool in ambiente Open Source - Pagina 74 di 84
4.6 Gestione di variabili e parametri
La gestione dei campi, delle variabili e dei parametri viene effettuata
mediante una finestra genericamente definita “finestra dei valori” (fig.
Fig.4.26: La finestra dei “valori”
4.26).
Mediante tale interfaccia è possibile aggiungere, modificare o cancellare
campi, variabili o parametri.
4.7 Compilazione ed esportazione
La compilazione permette di trasformare un file XML (scritto secondo la
sintassi di JasperReports) in un file jasper. In generale il codice XML
generato da iReport non contiene errori sintattici, tuttavia può capitare che
la compilazione generi degli errori dovuti ad un posizionamento invalido
degli elementi o a qualche errore java in un’espressione.
Per semplificare la vita del programmatore, iReport mette a disposizione
un sistema che trasforma gli errori generati in fase di compilazione in link
che puntano direttamente all’eventuale espressione errata (ovunque essa
si trovi), o all’elemento fuori posto.
Questa trasformazione avviene analizzando i messaggi di errore ed il file
java che JasperReports tenta di compilare per la generazione del file
Jasper.
In figura 4.27 è possibile vedere i link agli errori visualizzati da iReport
durante la compilazione di un documento di prova.
Reporting tool in ambiente Open Source - Pagina 75 di 84
Compilata la stampa è possibile testarla incovandone la generazione.
Fig.4.27: Link agli errori di compilazione
IReport visualizza i risultati esportandoli nel formato richiesto dall’utente,
selezionabile dal menu build. Mediante la finestra delle opzioni (menu
tools->options) è possibile associare un visualizzatore ad ogni formato di
stampa gestito da iReport.
4.8 Performance
Pur appoggiandosi a delle librerie grafiche molto pesanti (java swing),
l’interfaccia di
iReport appare abbastanza fluida
(soprattutto dopo gli
accorgimenti di Kees Kuip che ha introdotto diverse modifiche per
ottimizzare il motore grafico di iReport). Tuttavia la quantità di RAM
utilizzata è molto alta (in particolare quando vengono gestiti molti report
complessi contemporaneamente.
Tuttavia i feedback molto positivi ottenuti dagli utenti che sono passati
dalla veloce versione per win32
alla versione java, sono molto
incoraggianti.
Reporting tool in ambiente Open Source - Pagina 76 di 84
Per quel che riguarda le performance nella generazione delle stampe, non
sono mai stati fatti dei seri test comparativi con altri sistemi di reportistica
simili (quali DataVision e JFreeReport).
Tuttavia i tempi di risposta effettuati stampando in pdf diverse migliaia di
record sono del tutto accettabili (poco più lunghi di quelli ottenuti con una
stampa scritta direttamente con iText).
4.9 Un caso di studio: Sydran Services LLC
Sydran Services LLC. è una società americana nata nel 1992 per opera di
Matthew Shoenberg operante nel settore della ristorazione. Attualmente
gestisce oltre 264 ristoranti Burger King in otto stati americani; conta oltre
1200 dipendenti e fattura oltre 325 milioni di dollari l’anno.
Sotto la guida del responsabile IT della società, Mark Rhodes, Sydran ha
sviluppato Cheetah, un sistema di reportistica basato su un software open
source per la pubblicazione su web di report: OpenReports, sviluppato da
Eric Swenson (per altro coautore per conto di Sydran di Cheetah).
Neanche a dirlo, il cuore di OpenReports (e quindi di Cheetah), è
JasperReports.
Cheetah è utilizzato da una moltitudine di persone all’interno della società:
dai restaurant shift coordinator al CEO. Il sistema conta circa 1.400 utenti
registrati dei quali almeno 500
si avvalgono delle funzionalità di
generazione dei report.
4.9.1 Storia di Cheetah
Lo scorso anno Sydran percepisce la necessità di avere uno strumento di
generazione di report per rendere accessibili internamente le più disparate
informazioni relative ai numerosi esercizi gestiti: dati relativi agli acquisti,
alle informazioni fiscali, al costo delle vivande, ecc…
Il mondo open source è ancora lontano dagli occhi della società, che inizia
a muoversi valutando diversi noti pacchetti commerciali di reportistica:
Cognos, IntelliView, Acuate. Insoddisfatta dei software disponibili in
commercio (per la difficoltà di utilizzo o per il costo elevato delle licenze),
Reporting tool in ambiente Open Source - Pagina 77 di 84
tenta di sviluppare in casa un proprio strumento di reportistica utilizzando
pagine ASP sotto windows, ma il tentativo fallisce a causa della
complessità di design dei report. Viene così adottato un primo sistema di
reportistica basato su Microsoft Access e reso disponibile mediante
Windows Terminal Server. L’accesso viene inizialmente aperto ad uno
stretto numero di manager operanti nella zona limitrofa all’area di sviluppo,
per un totale di circa 60 utenti. Il sistema soffre tuttavia di una serie di
limitazioni:
-
necessita di una licenza Windows 2000 per ogni utente collegato al
terminal server (rendendo proibitivi i costi di un impiego di questa
soluzione esteso all’intera catena di ristoranti);
-
è privo di un sistema di autenticazione sufficientemente granulare (di
fatto un qualsiasi utente è in grado di effettuare query sui dati di tutti i
ristoranti);
-
è lento, essendo il sistema basato solo su Microsoft Access;
-
le richieste hardware della terminal server farm per sostenere i soli 60
utenti sono importanti: ben 3 CompaQ Proliant dual processor a
1.6GHz, dotati di 2GB di memoria RAM;
Nel dicembre del 2002, Mark scopre JasperReports, OpenReports e
iReport, tutti software opensource e liberamente utilizzabili nel contesto
richiesto da Sydran. Non conoscendo java, Mark contatta Eric Swenson,
chiedendogli di adattare OpenReports alle esigenze di Sydran e
inviandogli una serie di specifiche iniziali. Nasce il progetto Cheetah, del
quale viene realizzato un primo prototipo in meno di un mese. Verrà reso
pubblico a febbraio 2003. Il sistema è dotato solo delle funzionalità di
base, inclusa la parte relativa alla sicurezza (autenticazione degli utenti,
ecc…), e dispone di circa 40 report sviluppati con iReport. Il progetto
cresce e viene sviluppato un modulo di gestione dei permessi e di
scheduling delle stampe per l’invio automatico dei report agli utenti via
email. Attualmente Cheetah mette a disposizione 85 differenti tipi di report
organizzati per categoria.
Reporting tool in ambiente Open Source - Pagina 78 di 84
4.9.2 Obiettivo raggiunto
Il progetto Cheetah è risultato essere per Sydran vincente su tutti i fronti:
-
ampia disponibilità del servizio di reportistica mediante l’uso di
un’interfaccia web e protocollo SSL;
-
totale utilizzo di software per la realizzazione del sistema di reportistica
privo di costose licenze per l’utente (webworks, tomcat, jasper, iReport,
JasperReports, iText, poi, quartz,…); Sydran ha provveduto, tuttavia, a
elargire donazioni a molti dei progetti citati (iReport incluso);
-
dotazione di una infrastruttura per la gestione della sicurezza ad hoc,
dotata di notevoli funzioni di auditing e logging delle attività degli utenti;
-
impiego di query SQL ottimizzate per il database utilizzato (MS SQL
Server 2000);
-
disponibilità di funzioni particolari come lo scheduling dei report
(mediante Quartz) e la gestione delle stampe preferite;
-
economicità delle risorse hardware richieste (attualmente un solo
server Linux supporta tutti i 1.500 utenti; sono stati condotti test con 80
utenti concorrenti registrando un minimo calo delle performance del
sistema;
Grazie ai log registrati da Cheetah, è stato calcolato che il numero di
report generati raggiunge il suo picco mediamente il martedì, con oltre
1.200 stampe, mentre la domenica rappresenta il giorno in cui il servizio è
meno usato (con una media di circa 300 stampe giornaliere).
La velocità di generazione della stampa si aggira normalmente attorno ai
22 secondi (un tempo relativamente basso dato il formato di esportazione
dei report: il pdf).
Secondo le stime effettuate da Mark, il sistema è in grado di reggere nello
stato attuale fino a 200 utenti concorrenti; il sistema è stato comunque
progettato per poter essere utilizzato su un cluster di server Linux
mediante il quale si potrebbe ottenere un notevole aumento delle
prestazioni.
L’analisi dei log, relativi a 10 giorni di utilizzo, inviatomi da Mark, permette
di evidenziare come il servizio sia rimasto perennemente attivo (7 giorni su
7, 24h su 24h) nel periodo monitorato, producendo un totale di 6.541
report eseguiti alla velocità media di 20,5 secondi per stampa.
Reporting tool in ambiente Open Source - Pagina 79 di 84
L’esperienza di Sydran dimostra come un sistema di reportistica basato
su JasperReports sia estremamente versatile e scalabile, paragonabile ai
più costosi sistemi di reportistica commerciali (le cui licenze, in molti casi,
variano di prezzo a seconda del volume di report generati!).
4.10 Sviluppi futuri
Il progetto iReport non ha ancora compiuto un anno. La lista delle
funzionalità da realizzare e completare è veramente lunga: si tratta di
implementare molti suggerimenti proposti dagli utenti, ma in cantiere c’è
anche lo sviluppo di diverse funzionalità presenti in altri programmi simili
(commerciali e non).
L’idea è quella di rilasciare le future release a breve distanza tra loro, per
tenere alto l’interesse nel programma ed incoraggiare gli utenti a provare
le nuove funzionalità.
Diverse sono le richieste di rendere il programma localizzabile,
caratteristica che ne favorirebbe la diffusione nei paesi che usano
codifiche di caratteri particolari (come quelli arabi e asiatici).
Ritengo lo sviluppo della sorgente dati per file XML una funzionaità
indispensabile per un software di reportistica al passo con i tempi.
Il supporto di elementi speciali quali il grafico, il codice a barre, le immagini
vettoriali, ecc… arriveranno con il tempo, ma certamente iReport è
destinato a crescere. Molto.
Reporting tool in ambiente Open Source - Pagina 80 di 84
Conclusioni
In questa tesi, come ci si poteva aspettare, sono stati fatti pochissimi
riferimenti alle soluzioni commerciali per lo sviluppo di report. Quanto a
funzionalità, iReport è probabilmente ancora molto lontano da molte di
queste soluzioni, ma è in grado di rispondere efficacemente ad un buon
80% delle richieste avanzate dagli utenti che necessitano di un software di
reportistica.
Tuttavia, la diffusione dei reporting tool in ambiente Open Source è
osteggiata in maniera decisa dalle software house commerciali, logorate
già da una feroce concorrenza [8] nel settore dei reporting tool.
In un articolo intitolato “Build Reporting into Applications” [7] , apparso sul
numero di novembre 2003 del noto magazine americano JavaPro, Peter
Varhol analizza con estrema attenzione gli scenari di utilizzo dei reporting
tool ed cita praticamente tutti i prodotti commerciali disponibili sul mercato
elencandone caratteristiche e funzionalità; l’autore trae alcune conclusioni
sull’utilità di questi pacchetti, considerandoli indispensabili in un progetto
che necessiti di funzionalità di reportistca, e giustifica il costo di queste
soluzioni, per quanto alto, azzardando un confronto con quello di un
eventuale sviluppo di una soluzione proprietaria per la gestione delle
stampe. Nell’articolo non viene minimamente citato alcun software di
reportistica open source. Eppure l’attuale classifica stilata dalla nota rivista
Java Developer Jurnal [19] riguardo ai software maggiormente apprezzati
dagli utenti Java per la categoria reporting tool (JDJ Reader’s choise
2003) vede JasperReports e JFreeReport piazzati nelle prime cinque
posizioni! Senza commentare il fatto che JFreeReport risulta più votato di
Reporting tool in ambiente Open Source - Pagina 81 di 84
JasperReports, tutti i rimanenti concorrenti più votati sono sponsor ufficiali
dell’iniziativa.
La soddisfazione di veder crescere giorno dopo giorno una nutrita
comunità di utenti sparsi in tutto il mondo ed entusiasti di iReport è tuttavia
impagabile. I due forum ufficiali contano ormai oltre 1800 messaggi di
persone che scrivono suggerimenti, richiedono aiuto e offrono soluzioni,
ma soprattutto apprezzano il programma.
Le statistiche relative ai download di iReport indicano un chiaro trend
rialzista, e spero di poter vedere presto questo programma ai primi posti
delle prossime edizioni della classifica stilata da JDJ. D’altra parte,
superando la soglia dei 20.000 download in meno di un anno, iReport ha
già abbondantemente decretato il successo dell’ Open Source nella
combattuta nicchia di mercato contesa dai reporting tool.
Reporting tool in ambiente Open Source - Pagina 82 di 84
Bibliografia
[1] Teodor Danciu - JasperReports Ultimate Guide - 2002
[2] Jim Menard - DataVision User's Manual - 2003
[3] Giulio Toffoli - iReport 0.2.x Manual - 2003
[4] Tetsuya Masuishi, Nobuo Takahashi - A Reporting Tool Using
“Programming by Example” For Format Designation
[5] Don Kiely - Add Reporting to Your Apps – VisualStudio Magazine,
novembre 2003
[6] Andy Clark - Develop Flexible Reports – VisualStudio Magazine,
maggio 2003
[7] Peter Varhol - Build Reporting into Applications – VisualStudio
Magazine, novembre 2003
[8] ReportingEngines - Too Many Reporting Tools? - JavaPro Magazine,
novembre 2003
[9] QuestSoftware - J2EE Server-Side Components - JavaPro Magazine,
novembre 2003
[10] InetSoft - Integrated Reporting - JavaPro Magazine, novembre 2003
[11] CrystalDecisions - Crystal Reports and Java - JavaPro Magazine,
novembre 2003
[12] ReportMill Software - Object Reporting - JavaPro Magazine,
novembre 2003
[13] Panscopic - Back to Business - JavaPro Magazine, novembre 2003
[14] ExtenTech - Unlock Business Intelligence - JavaPro Magazine,
novembre 2003
[15] Jinfonet Software - JReport for Enterprise-Ready Reporting - JavaPro
Magazine, novembre 2003
Reporting tool in ambiente Open Source - Pagina 83 di 84
[16] Cognos - Cognos ReportNet™: The next generation of
enterprisenterprise query and reporting - A cognos white paper –
Agosto 2003
[17] Joseph Lauer - Reporting Tool, Evaluation Process
[18] Crystal Decision - Extending Crystal Reports’ Technology into the
Java World - 2002
[19] JDJ Reader’Choise 2003: Best Java Reporting Tool (http://www.syscon.com/java/readerschoice2003/liveupdate.cfm?BType=21)
Reporting tool in ambiente Open Source - Pagina 84 di 84