Documente Academic
Documente Profesional
Documente Cultură
Realizarea rapoartelor
Titlul (Title)
Detaliere (Detail)
Recapitulare (Summary)
Titlul
Banda pentru titlu este prima dintr-un raport. Un raport conŃine numai o
singură bandă pentru titlu. Aceasta poate fi dispusă pe o pagină separată.
Capul paginii
Banda pentru capul paginii apare la începutul fiecărei pagini a raportului.
Dacă titlul raportului sau recapitularea apar pe pagini separate, acestea nu vor
conŃine această regiune.
Capul coloanei
InformaŃiile dintr-un raport pot fi dispuse pe una sau mai multe coloane.
154
Raport pe o coloană
(date dispuse tabelar)
Column header
1.
2.
3.
4.
Detaliere
În cazul rapoartelor în care informaŃia nu este grupată, în această regiune
sunt afişate rânduri conŃinând date preluate din baza de date.
În cazul rapoartelor în care informaŃia apare organizată în grupuri, în această
regiune vor alterna benzi conŃinând antetul grupului (Group Header) respectiv datele
conŃinute în grup. După fiecare grup este posibilă afişarea unei benzi (Group Footer)
conŃinând un rezumat legat de datele conŃinute în grupul respectiv.
Picior coloană
Banda care încheie coloana poate conŃine informaŃii recapitulative, de regulă
sume sau numărul de articole conŃinute în regiunea de detaliere.
Picior pagină
Toate paginile care conŃin o bandă destinată capului paginii pot conŃine în
partea de jos o bandă pentru informaŃii recapitulative la nivel de pagină. Este posibilă
includerea unei benzi distincte pentru ultima pagină a raportului (Last Page Footer).
155
Recapitulare
Banda pentru recapitulare (Summary) este adăugată la sfârşitul raportului,
eventual pe o pagină distinctă.
Fundal
Fundalul raportului (Background) poate fi impus. De regulă acesta constă
dintr-o imagine care va fi repetată pe toate paginile raportului.
Jasper Reports
Realizarea comodă a rapoartelor se poate face folosind o aplicaŃie specializată.
Există o multitudine de astfel de aplicaŃii, mai interesantă fiind Jasper Reports, o
soluŃie gratuită (open source) propusă de JasperSoft Corporation (fondată de românul
Teodor Danciu).
Jasper Reports constă dintr-o colecŃie de clase Java care pot fi adăugate
aplicaŃiilor scrise în acest limbaj. Jasper Reports oferă de altfel o mulŃime de funŃii.
Astfel, pe lângă vizualizarea şi imprimarea imediată a raportului, datele acestuia pot fi
exportate într-o multitudine de formate: HTML, XML, XLS (Microsoft Excel), RTF
(Microsoft Word), PDF sau reprezentate grafic.
Principial un ciclu de lucru pentru crearea unui raport folosind Jasper Reports
constă din paşii următori:
1. Se crează un fişier de descriere a raportului în format XML, având extensia
.jrxml;
2. Fişierul .jrxml este compilat pentru a-l aduce într-o formă accesibilă
claselor Jasper Reports;
3. Se realizează interogarea sursei de date pentru aducerea datelor care vor fi
conŃinute în raport;
4. Se vizualizează şi se imprimă raportul.
Deoarece fişierul de descriere a raportului în format XML este relativ dificil de
creat, mai ales pentru rapoarte având o grafică îngrijită şi o structură nu tocmai
banală, în practică se foloseşte o aplicaŃie independentă, iReport. Autorul acesteia
este Giulio Toffoli (Italia, 2002). Sesizând interesului cu care a fost primită soluŃia
Jasper Reports de programatorii în Java, acesta a creat un mediu vizual destinat
realizării rapoartelor, bazat pe JasperReports. Acesta permite crearea interactivă a
raportului dorit şi salvarea fişierului în format .jrxml conŃinând descrierea acestuia.
ex.printStackTrace();
poza.setIcon(new javax.swing.ImageIcon("./Poze/disconect.jpg"));
}
}
Exemplul 1
Să se creeze un raport care să afişeze editurile de la care provin cărŃile din
bibliotecă.
Tot folosind mouse-ul se pot modifica lăŃimile zonelor raportului sau se pot
deplasa (rearanja) obiectele în cadrul zonelor sau pot fi deplasate dintr-o regiune
într-alta.
Cele mai folosite sunt java.lang.String (asociată tipurilor SQL CHAR sau
VARCHAR2), java.math.BigDecimal (asociată implicit tipului SQL NUMBER) şi
java.util.Date (asociat tipului SQL DATE). Pentru referirea la câmpuri se foloseşte
sintaxa:
$F{nume_camp}
Variabilele servesc la producerea unor valori care variază de la o linie la alta
(un contor de linii de exemplu) sau a unor valori calculate pe baza valorilor
câmpurilor (sume, medii, valori extreme etc.). AplicaŃia iReports defineşte implicit un
număr de variabile.
Parametrii sunt obiecte având valori fixe, definite în momentul declarării lor.
AplicaŃia care va genera efectiv raportul va înlocui însă valorile implicite ale acestora
168
cu valorile lor efective (înaintea populării cu date a raportului prin interogarea bazei
de date).
Pentru a referi un parametru se foloseşte sintaxa:
$P{nume_parametru}
Rezultat posibil:
Modul de operare a unei legături (inner join, left/right outer join) poate fi
impus selectând cu un dublu clic marcajul de pe arcul care indică legătura.
Adăugarea condiŃiilor suplimentare incluse în clauza where se realizează
selectând în arborele din panoul drept WHERE/add condition.
Dacă liniile raportului trebuie să fie numerotate, o soluŃie este inserarea unei
variabile ale cărei valori vor fi afişate în prima coloană a raportului.
Pentru inserarea unei variabile se va selecta cu butonul drept al mouse-ului
intrarea Variables din fereastra Document structure şi apoi se va alege în meniul
contextual Add... / Variable.
ProprietăŃile casetei vor fi modificate astfel încât textul afişat să aibă aceleaşi
caracteristici cu cel afişat de celelalte casete de text. Pentru a impune conŃinutul
casetei se va selecta tabul Text field valorile fiind setate ca în figură.
175
Rezultat posibil:
În această etapă raportul poate fi salvat (File / Save, rezultatul fiind un fişier
în format .jrxml).
raportului se impun valorile efective ale celor doi parametri. Acestea provin din două
controale ale formularului realizat în acest scop. SecvenŃa de cod prezentată este
executată la apăsarea butonului ButonRaport de pe acelaşi formular.
Pentru afişarea şi imprimarea altor rapoarte ale aplicaŃiei funŃiile necesare vor
fi similare celei scrise, singura diferenŃă fiind numele fişierului .jrxml şi secvenŃa de
preluare a valorilor eventualilor parametri.
SELECT
CARTI."TITLU" AS CARTI_TITLU,
CARTI."AN_APAR" AS CARTI_AN_APAR,
EDITURI."NUME" AS EDITURI_NUME,
EDITURI."TELEFON" AS EDITURI_TELEFON
FROM
"BIBLIO"."EDITURI" EDITURI INNER JOIN "BIBLIO"."CARTI" CARTI ON
EDITURI."COD_EDIT" = CARTI."COD_EDIT"
ORDER BY EDITURI.NUME ASC, CARTI.TITLU ASC
178
179
În urma testării, aplicaŃia trebuie pregătită astfel încât să poată fi lansată în execuŃie
şi fără utilizarea mediului de programare Netbeans. Pentru a realiza aceasta se va
selecta opŃiunea Build / Build Main Project. Mediul de programare va adăuga directorului
aplicaŃiei un subdirector denumit dist care va coŃine o arhivă .jar executabilă. Pe lângă
aceasta directorul dist va mai conŃine subdirectorul lib. În acest subdirector mediul
Netbeans va copia toate bibliotecile adăugate proiectului în timpul realizării sale (în
Libraries).
Dacă aplicaŃia mai conŃine fişiere şi în alte directoare, şi este de regulă cazul
fişierelor .jrxml care conŃin descrierea rapoartelor, în dist vor trebui copiate şi aceste
directoare. În exemplul ales s-au copiat două subdirectoare, Rapoarte şi Poze.
Lansarea în execuŃie fără Netbeans se realizează selectând arhiva executabilă cu
butomul drept al mouse-ului şi apoi Open With / Java Platform SE binary.
181
Laborator nr. 11
• declaraŃi patru variabile globale , două de tip Statement şi două de tip ResultSet:
182
Statement autorii ;
ResultSet rezultat_autorii ;
Statement editurile ;
ResultSet rezultat_editurile ;
autor.removeAllItems();
while (rezultat_autorii.next()) {
String n = rezultat_autorii.getString("nume")+rezultat_autorii.getString("prenume");
autor.addItem(n);
}
editura.removeAllItems();
while (rezultat_editurile.next()) {
String n = rezultat_editurile.getString("nume");
editura.addItem(n);
}
• la închiderea formularului trebuie distruse cele două obiecte din clasa Statement:
private void CartiAutWindowDeactivated(java.awt.event.WindowEvent evt) {
// TODO add your handling code here:
try {
autorii.close();
editurile.close();
183
• adăugaŃi clasei principale două variabile, codaut şi codedit pentru preluarea codurilor
autorului şi editurii selectate;
• la modificarea elementului selectat din controlul de tip JComboBox autor preluaŃi codul
autorului selectat de utilizator, astfel:
try {
// Se selecteaza codul autorului
int linie = autor.getSelectedIndex();
if (linie>=0){
rezultat_autorii.absolute(linie+1);
codaut = rezultat_autorii.getInt("Cod_aut");
}
} catch (SQLException ex) {
ex.printStackTrace();
}
tit = titlu.getText();
184
an = anul.getText();
// Creez un Statement*/
Statement stm = cnx.createStatement();
System.out.println(fraza1SQL);
stm.executeUpdate(fraza1SQL);
stm.close();
//golesc campurile
titlu.setText("");
anul.setText("");
• adăugaŃi clasei principale patru variabile, două de tip Statement şi două de tip ResultSet:
Statement cititorii ;
ResultSet rezultat_cititorii ;
Statement cartile ;
ResultSet rezultat_cartile ;
• la deschiderea formularului trebuie rulat codul pentru popularea celor două controale de
tip JComboBox, unul pentru lista codurilor cititorilor şi celălalt pentru lista cartilor din
baza de date şi pentru popularea textboxului cu data curentă (data sistemului):
try {
//populez lista cu codurile cititorilor
cititorii = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rezultat_cititorii = cititorii.executeQuery("SELECT * from cititori order by cod_cit");
cod_cititor.removeAllItems();
while (rezultat_cititorii.next()) {
String n = rezultat_cititorii.getString("cod_cit");
cod_cititor.addItem(n);
}
cartea.removeAllItems();
while (rezultat_cartile.next()) {
String n = rezultat_cartile.getString("titlu");
cartea.addItem(n);
}
try {
cititorii.close();
cartile.close();
} catch (SQLException ex) {
ex.printStackTrace();
}
ObservaŃie: după selectarea codului cititorului (scanarea de ex. cu cititorul de coduri de bare
de pe legitimaŃia de bibliotecă), se fac mai multe lucurui simultan:
a. se afişează datele de identificare ale acestuia în cele două controlae de tip JTextField;
b. se populeaza controlul de tip JTable cu cărŃile împrumutate de respectivul cititor
c. adăugaŃi clasei principale variabila codcit pentru preluarea codului cititorului selectat;
d. adăugaŃi aplicaŃiei o nouă clasă, TbModel_3 derivată din AbstractTableModel.
try{
while(rs.next()){
ArrayList linie = new ArrayList();
String cartea = rs.getString("titlu");
Date datai = rs.getDate("data_imprumut");
Date datar = rs.getDate("data_rest");
linie.add(cartea);
linie.add(datai);
linie.add(datar);
dateContinute.add(linie);
}
} catch(Exception e){
System.out.println("Exceptie in TbModel");
}
return dateContinute.size();
// return date1Continute.size();
}
try {
// Se selecteaza codul autorului
int linie = cod_cititor.getSelectedIndex();
if (linie>=0){
rezultat_cititorii.absolute(linie+1); // mut cursorul in cited_rs pe linie
codcit = rezultat_cititorii.getInt("cod_cit");
// populez tabelul
Statement carti_stmt = null;
ResultSet rs = null;
try {
carti_stmt = cnx.createStatement();
String fraza;
fraza = "SELECT titlu, data_imprumut, data_rest FROM carti, cititori, imprumut";
fraza += " WHERE imprumut.cod_carte = carti.cod_carte ";
fraza += "and imprumut.cod_cit = cititori.cod_cit ";
fraza += "and cititori.cod_cit=" +codcit;
System.out.println(fraza);
rs = carti_stmt.executeQuery(fraza);
jTable1.setModel(new TbModel_3(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn coloana0 = null;
TableColumn coloana1 = null;
coloana0 = citcarti.getColumnModel().getColumn(0);
coloana1 = citcarti.getColumnModel().getColumn(1);
coloana0.setPreferredWidth(140);
coloana1.setPreferredWidth(80);
} catch (SQLException ex) {
ex.printStackTrace();
188
//populez textboxurile
try {
comanda = cnx.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
rezultat = comanda.executeQuery("SELECT nume, prenume, cnp FROM cititori
WHERE cod_cit="+codcit);
if (rezultat.next()) {
String sir1 = rezultat.getString("nume")+" "+ rezultat.getString("prenume");
String sir2 = rezultat.getString("cnp");
cititorul.setText(sir1);
cod_numeric.setText(sir2);
}
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
• pentru înregistararea unui nou împrumut preluaŃi codul cărŃii împrumutate astfel:
try {
// TODO add your handling code here:
}
} catch (SQLException ex) {
ex.printStackTrace();
}
try {
String frazaSQL ;
frazaSQL = "INSERT into imprumut VALUES (" ;
frazaSQL += codcit + "," + codcarte + ","+ apostrof(dataimpr.getText())+",'')";
// Creez un Statement*/
Statement stm = cnx.createStatement();
// Apelez metoda executeUpdate() pt. a trimite comanda INSERT
stm.executeUpdate(frazaSQL);
stm.close();
rs = carti_stmt.executeQuery(fraza);
jTable1.setModel(new TbModel_3(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn coloana0 = null;
TableColumn coloana1 = null;
coloana0 = citcarti.getColumnModel().getColumn(0);
coloana1 = citcarti.getColumnModel().getColumn(1);
coloana0.setPreferredWidth(140);
coloana1.setPreferredWidth(80);
//golesc capurile
cititorul.setText("");
cod_numeric.setText("");
try {
//populez lista cu codurile cititorilor
cititorii = cnx.createStatement(ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_READ_ONLY);
rezultat_cititorii = cititorii.executeQuery("SELECT * from cititori order by cod_cit");
cod_cititor1.removeAllItems();
while (rezultat_cititorii.next()) {
String n = rezultat_cititorii.getString("cod_cit");
cod_cititor1.addItem(n);
}
cartea1.removeAllItems();
while (rezultat_cartile.next()) {
String n = rezultat_cartile.getString("titlu");
cartea1.addItem(n);
}
ObservaŃie: după selectarea codului cititorului (ca şi în cazul formularului care înregiatrează
un împrmut), se execută mai multe acŃiuni:
a. se afişează datele de identificare ale acestuia în cele două controlae de tip
JTextField;
b. se populează controlul de tip JTable cu cărŃile împrumutate şi nerestituite (!) de
respectivul cititor.
try{
while(rs.next()){
ArrayList linie = new ArrayList();
String cartea = rs.getString("titlu");
Date datai = rs.getDate("data_imprumut");
linie.add(cartea);
linie.add(datai);
dateContinute.add(linie);
}
} catch(Exception e){
System.out.println("Exceptie in TbModel");
}
return rand_cautat.get(col);
try {
// Se selecteaza codul cititorului
int linie = cod_cititor1.getSelectedIndex();
if (linie>=0){
rezultat_cititorii.absolute(linie+1); // mut cursorul pe linie
codcit = rezultat_cititorii.getInt("cod_cit");
System.out.println(codcit);
// populez tabelul
Statement carti_stmt = null;
ResultSet rs = null;
try {
carti_stmt = cnx.createStatement();
String fraza;
fraza = "SELECT carti.titlu, imprumut.data_imprumut";
fraza += " FROM carti, cititori, imprumut";
fraza += " WHERE imprumut.cod_carte = carti.cod_carte ";
fraza += "and imprumut.cod_cit = cititori.cod_cit ";
fraza += "and imprumut.data_rest is null ";
fraza += "and cititori.cod_cit=" +codcit;
System.out.println(fraza);
rs = carti_stmt.executeQuery(fraza);
jTable2.setModel(new TbModel_3_1(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn coloana0 = null;
TableColumn coloana1 = null;
193
coloana0 = citcarti.getColumnModel().getColumn(0);
coloana1 = citcarti.getColumnModel().getColumn(1);
coloana0.setPreferredWidth(140);
coloana1.setPreferredWidth(80);
}
// //populez combo-ul cu cartile nerestituite
try {
carti_nerest = cnx.createStatement(
ResultSet.TYPE_SCROLL_INSENSITIVE,
ResultSet.CONCUR_UPDATABLE);
String fraza1;
fraza1 = "SELECT carti.titlu, carti.cod_carte ";
fraza1 += " FROM carti, cititori, imprumut";
fraza1 += " WHERE imprumut.cod_carte = carti.cod_carte ";
fraza1 += "and imprumut.cod_cit = cititori.cod_cit ";
fraza1 += "and imprumut.data_rest is null ";
fraza1 += "and cititori.cod_cit=" +codcit;
System.out.println(fraza1);
rs_nerest = carti_nerest.executeQuery(fraza1);
cartea1.removeAllItems();
while (rs_nerest.next()) {
String n = rs_nerest.getString("titlu");
cartea1.addItem(n);
}
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
}
} catch (SQLException ex) {
ex.printStackTrace();
}
• la apăsarea butioului "Introducere" se caută înregistrarea cu codcit şi codcarte1 din
tabelul imprumut şi se trimite o frază UPDATE (data se preia din sistem):
try {
String fraza2SQL ;
fraza2SQL = "UPDATE imprumut SET data_rest =";
fraza2SQL += apostrof(datarest.getText()) ;
fraza2SQL += "WHERE cod_carte = "+ codcarte1 + " and cod_cit = "+codcit;
// Creez un Statement*/
Statement stm = cnx.createStatement();
// Apelez metoda executeUpdate() pt. a trimite comanda UPDATE
stm.executeUpdate(fraza2SQL);
stm.close();
jTable2.setModel(new TbModel_3_1(rs));
carti_stmt.close();
// Redimensionez prima coloana
TableColumn coloana0 = null;
TableColumn coloana1 = null;
coloana0 = citcarti.getColumnModel().getColumn(0);
coloana1 = citcarti.getColumnModel().getColumn(1);
coloana0.setPreferredWidth(140);
coloana1.setPreferredWidth(80);
Laborator nr. 12
Rapoarte
4. Raportul creat:
• rulaŃi raportul: Build -> Execute (with active connection) sau butonul
• salvaŃi raportul. Pentru aceasta creaŃi în directorul aplicaŃiei Java biblio subdirectorul
Rapoarte.
198
• vizualizaŃi raportul:
• modificaŃi aspectul (titlu propriu, redenumire coloane, font, culoarea font) folosind fereastra
de proprietăŃi;
where "AUTCARTI"."COD_AUT"="AUTORI"."COD_AUT"
and "AUTCARTI"."COD_CARTE"="CARTI"."COD_CARTE"
and "EDITURI"."COD_EDIT"="CARTI"."COD_EDIT"
order by CARTI.TITLU ASC, EDITURI.NUME ASC, AUTORI.NUME ASC !!!
După gruparea pe trei nivele, alegerea aspectului, salvarea şi vizualizarea raportului un rezultat
posibil ar fi următorul: