84
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

Facolt  di Scienze Matematiche, Fisiche e Naturali Corso di

  • Upload
    others

  • View
    2

  • Download
    0

Embed Size (px)

Citation preview

Alma Mater StudiorumUniversità degli Studi di Bologna

Facoltà di Scienze Matematiche, Fisiche e NaturaliCorso 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

Reporting tool in ambiente Open Source - Pagina 2 di 84

Cinque parole chiave:

Reporting tool, visual builder, java printing, JasperReports, iReport

Reporting tool in ambiente Open Source - Pagina 3 di 84

A mia moglie Caterina

Reporting tool in ambiente Open Source - Pagina 4 di 84

Reporting tool in ambiente Open Source - Pagina 5 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 6 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 7 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 8 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 9 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 10 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 11 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 personalmente non ritengo di aver utilizzato

sufficientemente 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 12 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 13 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.

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

Fig.2.1: Struttura del layout

Reporting tool in ambiente Open Source - Pagina 14 di 84

generazione di report disponibile nel mondo open source, essendo l’unico

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

Fig.2.2: Il risultato della stampa generata mediante il layout in figura 1

Reporting tool in ambiente Open Source - Pagina 15 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 16 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 17 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.

Fig.2.3: Esempio di struttura dati ad albero

Root

Element 1

Element 1.1

Element 1.2

Element 2

Element 2.2

Element 2.3

Reporting tool in ambiente Open Source - Pagina 18 di 84

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.

Fig.2.4: Rappresentazione tabellare della struttura ad albero di figura 3

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

Reporting tool in ambiente Open Source - Pagina 19 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 20 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 21 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

report è la staticità di alcuni elementi base come le etichette o il numero di

colonne.

Fig.2.6: Tabular report

Fig.2.7: Crosstab report

Reporting tool in ambiente Open Source - Pagina 22 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 23 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 24 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 25 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 all’indirizzo

Reporting tool in ambiente Open Source - Pagina 26 di 84

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 27 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 28 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

a video della stampa come anteprima. Queste funzionalità vengono

utilizzate da normali programmi java che utilizzano le swing o all’interno di

Fig. 3.1: Esempio di anteprima mediante JasperReports

Reporting tool in ambiente Open Source - Pagina 29 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.

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.

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

Fig.3.2: Funzionamento di JasperReports

Fig.3.3: Contesti di utilizzo

Reporting tool in ambiente Open Source - Pagina 30 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 è

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

Fig.3.4: Bande predefinite in JasperReports

Reporting tool in ambiente Open Source - Pagina 31 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).

In generale, in JasperReports esistono delle regole che determinano

l’altezza massima di una banda, mentre la larghezza è sempre uguale alla

Fig.3.5: Differenza tra una colonna del dettaglio e una colonna di dati

Reporting tool in ambiente Open Source - Pagina 32 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 33 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

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

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.

Fig.3.6: Page header

Fig.3.7: Column header

Reporting tool in ambiente Open Source - Pagina 34 di 84

Group header Un report può contenere zero o più bande di

raggruppamento, ovvero sezioni che permettono di dividere in veri

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.

Fig.3.8: Group header

Reporting tool in ambiente Open Source - Pagina 35 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 36 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 37 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 #REQUIREDclass (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 38 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 39 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 40 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 41 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 nextrecord.", 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 = newByte((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 42 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 = newDouble((String)objValue);

}}else if

(clazz.equals(java.lang.Float.class)) {objValue =

resultSet.getString(field.getName());if(resultSet.wasNull()) {

objValue = null;} else {

objValue = newFloat((String)objValue);

}}else if

(clazz.equals(java.lang.Integer.class)) {objValue =

resultSet.getString(field.getName());if(resultSet.wasNull()) {

objValue = null;} else {

objValue = newInteger((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 = newLong((String)objValue);

}}else if

(clazz.equals(java.lang.Short.class)) {objValue =

resultSet.getString(field.getName());if(resultSet.wasNull()) {

objValue = null;} else {

objValue = newShort((String)objValue);

}}else if

(clazz.equals(java.math.BigDecimal.class)) {objValue =

Reporting tool in ambiente Open Source - Pagina 43 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 44 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 45 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 46 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 47 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 48 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 49 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 50 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 51 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

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.

Fig. 4.1: Statistiche progetto iReport (fonte SourceForge.net)

Pagine viste e num. di download(fonte SourceForge.net)

0

2000

4000

6000

8000

10000

12000

14000

16000

Octobe

r 200

2

Novem

ber 2

002

Decem

ber 2

002

Janu

ary 20

03

Febru

ary 20

03

March 2

003

April 2

003

May 20

03

June

2003

July 2

003

Augus

t 200

3

Septem

ber 2

003

Mesi (da ottobre 2002 a settembre 2003)

N. d

i do

wn

load

/pag

ine

vist

e

Reporting tool in ambiente Open Source - Pagina 52 di 84

Sempre relativamente al sito del progetto sono disponibili anche le

statistiche registrate mediante un servizio gratuito chiamato 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.

Fig. 4.2: Statistiche progetto iReport (fonte CQ Counter)

Accessi al sito ireport.sf.net (fonte CQ Counter)

0

2000

4000

6000

8000

10000

12000

Octobe

r 200

2

Decem

ber 2

002

Febru

ary 20

03

April 2

003

June

2003

Augus

t 200

3

Mesi (da ottobre 2002 a settembre 2003)

Nu

mer

o d

i co

nta

tti

Reporting tool in ambiente Open Source - Pagina 53 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 54 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 thatare well-known open-source web reporting solutions.Anybody who want to make web based reports easily and rapidlyis able to use this solution as a freeware for non-commercial use.iReportPlus made by iMobile Technology Inc. has some advancedfeatures as follows :- Report Designer with Wizards- Report Export as Jasper, Excel and PDF- Database Explorer- Server Explorer & Preview- Local Data ExploreriReportPlus also provides many functions other than those listed above.You can get more detailed information and download it fromhttp://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 55 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 56 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 57 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 58 di 84

compongono il report (figura 4.5). Mediante questi strumenti è possibile

portare in primo piano il documento da modificare o selezionare in

maniera rapida uno o più elementi del documento corrente.

Fig.4.4: Interfaccia principale di iReport

Fig.4.5: Struttura del documento

Reporting tool in ambiente Open Source - Pagina 59 di 84

Le caratteristiche di un nuovo documento (menu File->New document),

vengono richieste mediante un’apposita finestra di dialogo (figura 4.6).

È 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

Fig.4.6: Proprietà del report

Reporting tool in ambiente Open Source - Pagina 60 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 61 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 62 di 84

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

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;

Fig. 4.8: Gerarchia degli elementi grafici gestiti da iReport

Elemento

Elemento grafico

Rettangolo

Linea

Immagine

Grafico

Elemento di testo

Testo statico

Campo di testo

Sottoreport

Fig.4.9: Scheda “Common”

Reporting tool in ambiente Open Source - Pagina 63 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 64 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;

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

Fig.4.10: Scheda “Graphics Element”

Reporting tool in ambiente Open Source - Pagina 65 di 84

caratteristica aggiuntiva di quest’ultimo (scheda Rectangle) è il raggio di

curvatura degli angoli qualora li si vuole arrotondati (il Radius).

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

Fig.4.11: Scheda “Line” Fig.4.12: Scheda “Rectangle”

Fig.4.13: Scheda “Image”

Reporting tool in ambiente Open Source - Pagina 66 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 67 di 84

Tutti i campi di testo possiedono le caratteristiche visualizzate nella

scheda Font:

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;

Fig.4.14: Scheda “Font” Fig.4.15: Scheda “Static Text”

Reporting tool in ambiente Open Source - Pagina 68 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.

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.16: Scheda “TextField”

Fig.4.17: Scheda “Subreport 1” Fig.4.18: Scheda “Subreport 2”

Reporting tool in ambiente Open Source - Pagina 69 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 70 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.

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…

Fig.4.20: Scheda “Chart”

Reporting tool in ambiente Open Source - Pagina 71 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.

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.

Fig.4.21: Definizione di una data source per file XML

Reporting tool in ambiente Open Source - Pagina 72 di 84

I parametri richiesti da questo tipo di sorgente dati sono: il nome da

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

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

Fig.4.22: Definizione di una JavaBean Set data source

Fig.4.23: Definizione di una Custom data source

Reporting tool in ambiente Open Source - Pagina 73 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

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.

Fig.4.24: Definizione di una fonte dati JDBC

Reporting tool in ambiente Open Source - Pagina 74 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

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.

Fig.4.25: Recupero dei campi di una query

Reporting tool in ambiente Open Source - Pagina 75 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.

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.

Fig.4.26: La finestra dei “valori”

Reporting tool in ambiente Open Source - Pagina 76 di 84

Compilata la stampa è possibile testarla incovandone la generazione.

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.

Fig.4.27: Link agli errori di compilazione

Reporting tool in ambiente Open Source - Pagina 77 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 78 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 79 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 80 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 81 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 82 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 83 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 84 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.sys-

con.com/java/readerschoice2003/liveupdate.cfm?BType=21)