Informatika | Tanulmányok, esszék » Informatikai navigátor, Gondolatok a szoftverek használatáról és fejlesztéséről VIII.

Alapadatok

Év, oldalszám:2013, 119 oldal

Nyelv:magyar

Letöltések száma:66

Feltöltve:2013. április 10.

Méret:2 MB

Intézmény:
-

Megjegyzés:

Csatolmány:-

Letöltés PDF-ben:Kérlek jelentkezz be!



Értékelések

Nincs még értékelés. Legyél Te az első!


Tartalmi kivonat

2013. Április Informatikai Navigátor Gondolatok a szoftverek használatáról és fejlesztéséről Riportok, nyomtatványok és grafikonok készítése 8. szám Informatikai Navigator Gondolatok a szoftverek használatáról és fejlesztéséről Tartalomjegyzék 1. JasperReports - Bevezető ismeretek 3 2. Adatbázis alapú dinamikus riport készítése 12 3. A JasperReports adatforrások használata 28 4. Hordozható dokumentum formátumok készítése 44 5. Többnyelvű riportok készítése 54 6. Változók és kifejezések használata 67 7. Az adatok csoportokba foglalása 76 8. Az iReport - A riport külalakjának megtervezése 88 9. Az alriportok (subreports) használata 93 10.Grafikonok használata 98 11.Táblázatos riportok készítése (Crosstab) 111 12.Képek és rajzok beszúrása 117 Főszerkesztő: Nyiri Imre (imre.nyiri@gmailcom) 2 JasperReports 1. JasperReports - Bevezető ismeretek JasperReports - Bevezető ismeretek A

JasperReports egy open source (LGPL), sokoldalú és kiemelkedő minőségű riportkészítő eszköz, aminek kiemenete támogatja az ismertebb formátumokat: PDF, HTML, XLS, DOC, RTF, ODT, CSV, TXT és XML. Teljes egészében Java nyelven íródott és gyakorlatilag ennek a platformnak az első számú megoldása lett. A webhelye: http://communityjaspersoftcom/ Mindezt kiegészíti egy magas színvonalú tervező szoftver, az iReport (http://communityjaspersoftcom/ project/ireport-designer). Aki komolyabb (Java) alkalmazásokat készít, annak mindenképpen célszerű ismernie ezt a programot, hiszen sokféle, nyomtatásra is alkalmas kimenetének szabványosított használatával kiváló eredményt érhetünk el és sok energiát takaríthatunk meg. 1.1 ábra: JasperReports - A működés folyamata (forrás: Ultimate Guide) A JasperReports áttekintése A képességek Teodor Danciu 2001-ben kezdte meg ennek a kiemelkedő képességű szoftvernek a fejlesztését. A JasperReports

legfontosabb jellemzői közül néhány: • XML nyelven (JRXML1 ) leírt riport definíció, széleskörű külalak megadási lehetőségekkel. • Szöveges és grafikus elemek használhatósága a riportokban. SQL select, XML, POJO (JavaBean), Java MAP. • Vízjelet (watermark ) helyezhetünk el. • A riportok tartalmazhatnak alriportokat is, ezzel jelentősen szélesedik azon feladatok száma, amiket ezzel az eszközzel könnyebben meg tudunk oldani. • Minden ismertebb dokumentumformátumot támogat. A JasperReports több ismert Java library-t • Többféle adatforrás (Datasource) meg- használ, így a feladatok jelentős részét ezekre deadási lehetőség: hagyományos adatbázis legálja tovább: 1 JRXML=JasperReports XML 3 JasperReports • iText: A PDF (és RTF, HTML, XML) dokumentumok előállítását és manipulálását támogató könyvtár. Többek között a digitális aláírási képességei is közkedveltek Webhelye: http://itextpdf.com/

JasperReports - Bevezető ismeretek JRDataSource interfésszel rendelkező különféle objektumok használata lett közkedvelt. • A riport szerkezeti tagolása, csoportosításai. • JFreeChart: Sokféle diagram és grafikon előállítási lehetősége elérhető a Jasper- Az 1-1. Programlista egy nagyon egyszerű, Hello Reports riportokba ágyazva. Webhelye: World típusú JRXML leírást mutat, ahol a riportban csak a „Helló Világ!” szöveg jelenik http://www.jfreeorg/jfreechart/ meg és nincs dinamikus adatforrás. A JRXML • Jakarta POI : A különféle Microsoft do- forrást a JasperReports eszközei ismerik (a gyakumentumok (XLS, DOC, PPT) előállítá- korlatban majd az iReport lesz legtöbbet haszsát és manipulálását lehet vele megvaló- nálva), így azt módosítani, javítani lehet. Ezt sítani. Az Apache Foundation keretében nevezzük a riport tervezési (JasperDesign doműködő projekt webhelye: http://poi boz ) fázisának, aminek az eredménye a

módosított jrxml fájl lesz Miután elégedettek lettünk apache.org/ a riport szerkezetével és kinézetével, azt lefordít• JAXP : Szabványos Java könyvtár XML hatjuk Java bináris formára (a JRCompiler class dokumentumok feldolgozására és előállítá- segítségével). Ennek az eredménye egy jasper kiterjesztésű fájl lesz, amit az ábra JasperReport sára. doboza szemléltet. Ez a bináris forma az, amit • Jakarta Commons: Egy Java könyvtár adatokkal feltöltve a riport készítéséhez felhaszgyűjtemény, ahol szinte minden újrahasz- nálhatunk. A riport elkészítése a fill művelet, nosításra alkalmas, általános célú rutin hatására egy .jrprint fájl generálódik le, ez maga megtalálható, tudását itt nézhetjük meg: az elkészített riport, natív JasperReports formátumban. Ezen fájlok képernyőn vagy nyomtatón http://commons.apacheorg/ való megjelenésére a környezet rendelkezik eszközökkel, de a gyakorlatban az export

műveletHogyan működik? tel előállítható és hordozható formátumok előálAz 1.1 ábra mutatja azt a folyamatot, amit lítása vált népszerűvé a riportok fejlesztése igényel. A fekete dobozok a logikai lépést, míg a pirosak az őket megA Hello World riport valósító Java osztályokat jelölik. Az első lépés (XML doboz ) a riport definíció elkészítése, amire Miután letöltöttük a JasperReports és iReport a JRXML nyelv szolgál. Itt a következő fonto- eszközöket, majd kicsomagoltuk őket egy számunkra megfelelő könyvtárba (a cikk írásakor sabb dolgokat adhatjuk meg: ez mindkét csomag esetén az 5.00 verzió volt), • A riport kinézete és tartalma. készítsük el a Hello World riportot! • A dinamikus adatforrás, hiszen a riporA riport megtervezése tok ilyet szinte mindig használnak. Itt jegyezzük meg, hogy az esetek nagy részé- A tervezés a számunkra megfelelő JRXML fájl ben nem itt szokás ezt megadni, helyette a elkészítését

jelenti, amit az 1-1. Programlista 4 JasperReports mutat. Minden riport a jasperReport gyökér elemmel kezdődik és érdemes betartani azt a névkonvenciót, hogy a name attribútum is a riport fájl neve legyen (esetünkben ez most HelloWorld). A riportok szekciókból állnak, mi ebből most csak a detail nevűt használtuk, amibe egy formázandó sávot (band ) tettünk be, ezen is csak egyetlen staticText elemmel. Ennek leírása 2 részből áll: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 JasperReports - Bevezető ismeretek • reportElement Mindegyik elemi riport darabka (komponens) esetén annak síkbeli méreteit és elhelyezkedését adja meg. • text A staticText komponens szövege, amit mindig érdemes CDATA-val levédeni, nehogy a behelyezett szöveg valahol megtörje a jrxml XML struktúrát. < !−− 1−1. P r o g r a m l i s t a : HelloWorld j r x m l −−> <?xml version=" 1 . 0 " ?> < !DOCTYPE j a s p e r R e p o r t PUBLIC

"−// J a s p e r R e p o r t s //DTD␣ Report ␣ Design //EN" " h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / d t d s / j a s p e r r e p o r t dtd "> <j a s p e r R e p o r t name=" HelloWorld "> < d e t a i l> <band h e i g h t=" 20 "> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 20 " y="0 " width=" 200 " h e i g h t=" 20 " /> <t e x t>< ! [CDATA[ H e l l ó V i l á g ! ] ]></ t e x t> </ s t a t i c T e x t> </band> </ d e t a i l> </ j a s p e r R e p o r t> fájlt készíteni (1-2. Programlista) és azon keresztül indítani őket Ez alól az iReport kivétel, A hatékony munka támogatására a JasperRe- mert az egy komplex RAD eszköz, amit külön ports több támogató eszközt is felkínál. Ezek tölthetünk le és saját indító paranccsal rendelkönnyű elérésére érdemes egy

ANT buildxml kezik A JasperReports eszközök használata 1 < !−− 1−2. P r o g r a m l i s t a : ant b u i l d xml −−> 2 3 <?xml version=" 1 . 0 " ?> 4 <p r o j e c t name=" H e l l o , ␣World" default="viewDesignXML" b a s e d i r=" . "> 5 <d e s c r i p t i o n>P r e v i e w s and c o m p i l e s our F i r s t Report</ d e s c r i p t i o n> 6 <p r o p e r t y name=" f i l e . name" v a l u e=" HelloWorld "/> 7 < !−− Ez a J a s p e r R e p o r t k ö n y v t á r −−> 8 <p r o p e r t y name=" j a s p e r . d i r " v a l u e="/home/ j a v a / J a s p e r R e p o r t s −5/ i R e p o r t − 5 0 0 / å i r e p o r t / modules "/> 9 <p r o p e r t y name="my . d i r " v a l u e="/home/ t a n u l a s / j a s p e r r e p o r t / pelda −1" /> 10 <p r o p e r t y name=" l i b . d i r " v a l u

e=" ${ j a s p e r d i r }/ e x t " /> 11 <p r o p e r t y name=" c l a s s e s . d i r " v a l u e=" ${my d i r }/ c l a s s e s " /> 12 13 < !−− A c l a s s p a t h h e l y e i −−> 5 JasperReports 14 15 16 17 18 19 20 21 22 JasperReports - Bevezető ismeretek <path i d=" c l a s s p a t h "> <p a t h e l e m e n t l o c a t i o n=" . / "/> <p a t h e l e m e n t l o c a t i o n=" ${ c l a s s e s . d i r } " /> < f i l e s e t d i r=" ${ l i b . d i r }"> <i n c l u d e name=" ∗ ∗ / ∗ . j a r "/> </ f i l e s e t> </ path> <t a r g e t name="viewDesignXML" d e s c r i p t i o n="A␣ Design ␣ Viewer ␣ h a s z n á l a t a ␣ megnézni ␣ aå ␣ t e r v e z e t t ␣XML␣ r e p o r t ␣ d e s i g n t "> <j a v a c l a s s n a m e=" n e t . s f j a s p e r r e p o r t s view J a s p

e r D e s i g n V i e w e r " f o r k=" t r u e "> <a r g v a l u e="−XML"/> <a r g v a l u e="−F${ f i l e . name } j r x m l "/> <c l a s s p a t h r e f i d=" c l a s s p a t h " /> </ j a v a> </ t a r g e t> 23 24 25 26 27 28 29 30 <t a r g e t name=" viewDesign " d e s c r i p t i o n="A␣ Design ␣ Viewer ␣ h a s z n n á l a t a ␣ megnézni ␣ a ␣å l e f o r d í t o t t ␣ r i p o r t o t "> <j a v a c l a s s n a m e=" n e t . s f j a s p e r r e p o r t s view J a s p e r D e s i g n V i e w e r " f o r k=" t r u e "> <a r g v a l u e="−F${ f i l e . name } j a s p e r " /> <c l a s s p a t h r e f i d=" c l a s s p a t h " /> </ j a v a> </ t a r g e t> 31 32 33 34 35 36 37 <t a r g e t name=" c o m p i l e " d e s c r i p t i o n="A␣ j r x m l ␣ f á j l

␣ f o r d í t á s a ␣ j a s p e r ␣ b i n á r i s ␣å f á j l r a "> <t a s k d e f name=" j r c " c l a s s n a m e=" n e t . s f j a s p e r r e p o r t s ant JRAntCompileTask "> <c l a s s p a t h r e f i d=" c l a s s p a t h " /> </ t a s k d e f> < j r c d e s t d i r=" . "> <s r c> < f i l e s e t d i r=" . "> <i n c l u d e name=" ∗ ∗ / ∗ . j r x m l " /> </ f i l e s e t> </ s r c> <c l a s s p a t h r e f i d=" c l a s s p a t h " /> </ j r c> </ t a r g e t> 38 39 40 41 42 43 44 45 46 47 48 49 50 51 <t a r g e t name=" view " d e s c r i p t i o n=" E l i n d í t j a ␣ a ␣ Report ␣ Viewert ␣ megnézni ␣ a ␣ j r p r i n t ␣å f á j l t "> <j a v a c l a s s n a m e=" n e t . s f j a s p e r r e p o r t s view J a s p e r V i e w e r " f o r k="

t r u e "> <a r g v a l u e="−F${ f i l e . name } j r p r i n t " /> <c l a s s p a t h r e f i d=" c l a s s p a t h " /> </ j a v a> </ t a r g e t> 52 53 54 55 56 57 58 59 60 61 <t a r g e t name=" c l e a n " d e s c r i p t i o n="Minden␣ g e n e r á l t ␣ f á j l t ␣ l e t ö r ö l "> <d e l e t e> < f i l e s e t d i r=" ${my . d i r }"> <i n c l u d e name=" ∗ ∗ / ∗ . j a s p e r "/> 6 JasperReports JasperReports - Bevezető ismeretek 62 </ f i l e s e t> 63 < f i l e s e t d i r=" ${my . d i r }"> 64 <i n c l u d e name=" ∗ ∗ / ∗ . j r p r i n t " /> 65 </ f i l e s e t> 66 </ d e l e t e> 67 </ t a r g e t> 68 69 <t a r g e t name=" w r i t e A p i "> 70 <mkdir d i r=" ${my . d i r }/ b u i l d / r e p o r t s " /> 71 <t a s k d e f

name=" jraw " c l a s s n a m e=" n e t . s f j a s p e r r e p o r t s ant JRAntApiWriteTask "> 72 <c l a s s p a t h r e f i d=" c l a s s p a t h " /> 73 </ t a s k d e f> 74 <jraw d e s t d i r=" ${my . d i r }/ b u i l d / r e p o r t s "> 75 <s r c> 76 < f i l e s e t d i r=" ${my . d i r }"> 77 <i n c l u d e name=" ∗ ∗ / ∗ . j a s p e r "/> 78 <i n c l u d e name=" ∗ ∗ / ∗ . j r x m l " /> 79 </ f i l e s e t> 80 </ s r c> 81 <c l a s s p a t h r e f i d=" c l a s s p a t h " /> 82 </ jraw> 83 </ t a r g e t> 84 </ p r o j e c t> • view : Elindítja a Report Viewert megnézni a jrprint fájlt • clean: Minden generált fájlt letöröl • writeApi Az ant script első 20 sora a meghívható parancsok (target-ek) működési környezetének beállításáról szól, ami lényegében azt jelenti most,

1.2 ábra: A Jasper Design Viewer alkalmazás hogy a Java CLASSPATH helyesen legyen beállítva, azaz ismert legyen az összes jar fájl A A fenti build.xml a következő target-eket, default target a viewDesignXML, ahogy azt a azaz parancsokat tartalmazza, amit a ant - 4. sor project tag-jénél látjuk is Ez azt jelenti, hogy az projecthelp paranccsal lehet kiíratni: • viewDesignXML: A Design Viewer haszná- ant viewDesignXML lata megnézni a tervezett XML report dehajtódik végre egy egyszerű ant parancsra, signt aminek eredményeképpen az 1.2 ábra ablaka jelenik meg. Ez annyit tud, hogy a minden• viewDesign: A Design Viewer hasznnálata kori design-t, azaz a JRXML vizuális kinézetet megnézni a lefordított riportot tekinthetjük meg vele. Esetünkben a filename • compile: A jrxml fájl fordítása jasper bi- script változó értéke HelloWorld, ugyanis a megnáris fájlra tekintendő fájl neve: HelloWorld.jrxml Itt a 7 JasperReports JasperReports - Bevezető

ismeretek XML argumentumnak pont az a szerepe, hogy tényleg a forrás tervet nézzük meg. Az ant compile parancs a már említett jrxml (XML szöveg) jasper (lefordított, bináris forma) fordítás végzi el a HelloWorld riportra, megkapva ezzel a HelloWorld.jasper fájlt Az Egy riport elkészítése után a HelloWorld.jrprint fájlt kapjuk, ami JasperReports formátumban tartalmazza a létrehozott jelentést. Az 13 ábra mutatja a Jasper Viewer alkalmazást, amit be lehet építeni a programunkba, mert képes a képernyőn megjeleníteni vagy akár kinyomtatni a keletkezett eredményt. ant view Desi gn Ez a JasperViewer osztály parancssorból is elhívás már ezzel a bináris, natív formával kéindítható: pes megmutatni a leendő jelentés kinézetét, amihez szintén a Jasper Design Viewer alkalmazást ant view használja. A build.xml clean opciója a generált fájlokat törli le A writeApi a JRAntApiWriteTask ant taszk használatát mutatja meg. Amennyiben lefuttatjuk,

úgy esetünkben most a build/reports könyvtárba nem a jasper fájlt generálja le, hanem helyette egy jrxmljava fordítást végez, azaz megtekinthetjük a riport definíció java forráskódját. Ez elsősorban hibakereséshez jelenthet egy hatékony eszközt, de a gyakorlatban erre nagyon ritkán kerül sor, amennyiben mi egy egyszerű riportkészítő programozók vagyunk. Érdekességként az 1-3 Programlista tartalmazza az így létrehozott java forráskódot, amire minden1.3 ábra: A Jasper Viewer alkalmazás képpen érdemes egy pillantást vetni. // 1−3. P r o g r a m l i s t a : HelloWorld j a v a /∗ ∗ Generated by J a s p e r R e p o r t s − 2 0 1 2 . 1 2 2 1 1 0 : 5 9 ∗/ import j a v a . awt C o l o r ; import o r g . j f r e e c h a r t p l o t P l o t O r i e n t a t i o n ; import o r g . j f r e e c h a r t r e n d e r e r xy XYBubbleRenderer ; import import import import import import import import import import import import net . net . net .

net . net . net . net . net . net . net . net . net . sf sf sf sf sf sf sf sf sf sf sf sf . . . . . . . . . . . . jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . charts ∗ ; . charts design ∗ ; . charts u t i l ∗ ; . crosstabs ∗ ; . crosstabs design ∗ ; . crosstabs f i l l calculation BucketDefinition ; . engine ∗ ; . e n g i n e b a s e JRBaseChartPlot J R B a s e S e r i e s C o l o r ; . e n g i n e b a s e JRBaseFont ; . engine design ∗ ; . engine type ∗ ; . engine u t i l ReportCreator ; public c l a s s HelloWorld implements R e p o r t C r e a t o r { 8 JasperReports JasperReports - Bevezető ismeretek public J a s p e r D e s i g n c r e a t e ( ) throws JRException { J a s p e r D e s i g n j a s p e r D e s i g n = new J a s p e r D e s i g n ( ) ; j a s p e r D e s i g n . setName ( " F i r s t R e p

o r t " ) ; j a sp e r D e s ig n . setLanguage ( " java " ) ; j a s p e r D e s i g n . setPageWidth ( 5 9 5 ) ; jasperDesign . setPageHeight ( 842) ; j a s p e r D e s i g n . setColumnWidth ( 5 5 5 ) ; j a s p e r D e s i g n . setColumnSpacing ( 0 ) ; jasperDesign . setLeftMargin ( 20) ; jasperDesign . setRightMargin ( 20) ; j a s p e r D e s i g n . setTopMargin ( 3 0 ) ; j a s p e r D e s i g n . setBottomMargin ( 3 0 ) ; JRDesignDataset r e p o r t M a i n D a t a s e t = new JRDesignDataset ( true ) ; r e p o r t M a i n D a t a s e t . setName ( " F i r s t R e p o r t " ) ; jasperDesign . setMainDataset ( reportMainDataset ) ; // d e t a i l B a n d // band name = d e t a i l B a n d 0 JRDesignBand d e t a i l B a n d 0 = new JRDesignBand ( ) ; detailBand0 . setHeight ( 20) ; d e t a i l B a n d 0 . s e t S p l i t T y p e ( n e t s f j a s p e r r e p o r t s e n g i n e t y p e SplitTypeEnum STRETCH) ; J R D e s i g n S t a t i c T e x t

detailBand0 0 = new J R D e s i g n S t a t i c T e x t ( j a s p e r D e s i g n ) ; detailBand0 0 . s e t P o s i t i o n T y p e ( n e t s f j a s p e r r e p o r t s e n g i n e t y p e PositionTypeEnum å FIX RELATIVE TO TOP) ; detailBand0 0 . setX ( 2 0 ) ; detailBand0 0 . setY ( 0 ) ; detailBand0 0 . setWidth ( 2 0 0 ) ; detailBand0 0 . s e t H e i g h t ( 2 0 ) ; JRParagraph detailBand0 0Paragraph = detailBand0 0 . g e t P a r a g r a p h ( ) ; detailBand0 0 . s e t T e x t ( " ␣ H e l l ó ␣ V i l á g ! ␣ " ) ; d e t a i l B a n d 0 . addElement ( detailBand0 0 ) ; ( ( J R D e s i g n S e c t i o n ) j a s p e r D e s i g n . g e t D e t a i l S e c t i o n ( ) ) g e t B a n d s L i s t ( ) add ( 0 , d e t a i l B a n d 0 ) ; } } return j a s p e r D e s i g n ; Általában persze nem parancssori eszköz• single star (*): Illeszkedik 0 vagy több karakterre a PATH neven belül, de annak csak egy adott zel dolgozunk, hanem az iReport tervezővel,

de szintjét tekintve. mégis érdemes az ismertetett ant script lehetőségeivel tisztában lennünk, mert egyrészt jobb át• double star (*): Illeszkedik 0 vagy több karakterre a PATH neven belül és a teljes directory úttekintést kapunk az eszközrendszerről, másrészt vonalat nézi, bizonyos feladatokat (tipikusan a jrxml jasper fordítást) hatékonyabban lehet vele elvégezni. • question mark (?): Pontosan 1 tetszőleges karakternyi illeszkedés a PATH neven belül Ugyanakkor a Jasper Viewer egy olyan kész panel, amit az alkalmazásainkba is beépíthetünk. A jobb megértés érdekében tekintsük a következő könyvtár és fájl elrendezést: 1. bartxt (a könyvtárban) Mielőtt továbblépnénk, szeretnénk pár szóban kitérni a build.xml -ben használt alábbi minták jelentésére, ugyanis ezek az ismeretek fontosak és ugyanakkor sokszor nem eléggé ismertek: 2. src/barc (a /src könyvtárban) 3. src/bazc (a /src könyvtárban) 4. src/test/bartestc (a

/src/test könyvtárban) 9 JasperReports JasperReports - Bevezető ismeretek Ekkor a *.c kifejezés nem illeszkedik semmire, mert az aktuális könyvtárban nincs ilyen, hiszen ott csak egy bar.txt van Az src/*.c illeszkedik a 2 és 3 fájlra is A */.c hasonlóképpen a 2 és 3 fájlokat választja ki, ugyanis a * csak 1 könyvtár szinten való illeszkedést jelent, a 4. sor pedig 2 könyvtárat is tartalmaz a bartestc előtt. Amennyiben mégis az összes *.c fájlt szeretnénk, úgy a */.c illeszkedik a 2, 3 és 4 fájlra is, mert a * több szintű könyvtárat jelent. A bar* természetesen csak az 1. fájlra illeszkedik, de a */bar.* már az 1. és 2. fájlokra is Nézzünk még 2 példát! A */bar.* az 1, 2 és 4. állományokra, míg az src/ba?c csak a 2 és 3 fájlokra illeszkedik. A riport előállítása és megtekintése Az eddigiek során elkészítettük a HelloWorld.jrxml riport tervet és a megfelelő ant paranccsal lefordítottuk azt, így jelenleg rendelkezünk a

HelloWorldjasper fájllal is Azt tudjuk, hogy a riportunk jelenleg semmilyen külső adatot nem igényel, egyedül csak egy statikus szöveget jelenít meg. Az 1-4 Programlista egy 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 olyan Java programot mutat, amivel elkészíthetjük a jelentésünket, azaz előállíthatjuk a HelloWorld.jrprint állományt Tekintsünk a forráskódra! A JRHelper class 23-26 sora közötti makeReport() metódus készíti el a riportot Ez gyakorlatilag a JasperFillManager osztály segítségével történik. Az 1 paraméter a jasper fájl neve, a 2 a külső paraméterek átvételét biztosító javautilMap objektum, míg a 3. egy külső adatforrást reprezentáló JRDataSource objektum Tekintettel arra, hogy most se paraméterünk nincs, se külső adatforrásunk, ezért üres Map-pel és a beépített JREmptyDataSource objektummal hívjuk meg a main() 40. sorában A JRHelper compile() metódusát általában nem programozottan használjuk,

de ugyanazt csinálja, mint az ismertetett ant compile parancs. Ennek az az oka, hogy egy jól letesztelt riportnak általában nem a külalakja változik, hanem a feldolgozott külső adatok, így azt hatékonysági okokból sem érdemes állandóan újrafordítani. // 1−4. P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; import import import import import import j a v a . u t i l HashMap ; net . s f j a s p e r r e p o r t s net . s f j a s p e r r e p o r t s net . s f j a s p e r r e p o r t s net . s f j a s p e r r e p o r t s net . s f j a s p e r r e p o r t s . e n g i n e JRDataSource ; . e n g i n e JREmptyDataSource ; . e n g i n e JRException ; . e n g i n e JasperCompileManager ; . engine JasperFillManager ; /∗ ∗ ∗ ∗ @author i n y i r i ∗/ public c l a s s JRHelper { public void c o m p i l e ( S t r i n g jrxmlFileName ) throws JRException { JasperCompileManager . c o m p i l e R e p o r t T o F i l e ( jrxmlFileName )

; } public void makeReport ( S t r i n g j a s p e r F i l e N a m e , HashMap params , JRDataSource j r D s ) throws å JRException { J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r F i l e N a m e , params , j r D s ) ; } 24 25 26 27 28 29 public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { 10 JasperReports 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 JasperReports - Bevezető ismeretek S t r i n g j r x m l F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/ HelloWorld . j r x m l " ; S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/ HelloWorld . j a s p e r " ; JRHelper j h = new JRHelper ( ) ; // // System . o u t p r i n t l n (" Compiling r e p o r t " ) ; jh . compile ( j r x m l F i l e ) ; System . out p r i n t l n ( "Make␣ r e p o r t " ) ; JRDataSource e d s = new

JREmptyDataSource ( ) ; j h . makeReport ( j a s p e r F i l e , new HashMap ( ) , e d s ) ; } System . out p r i n t l n ( "Done ! " ) ; } // end c l a s s A JRHelper program lefuttatása után keletkezik a HelloWorld.jrprint fájl, amit a már ismert eszközzel (13 ábra) lehet megnézni az ant view parancs segítségével. Végezetül vessünk egy pillantást az iReport RAD eszközre (1.4 ábra), és haladjunk tovább a következő fejezeteken, amik áttekintik a JasperReports összes fontos lehetőségét! 1.4 ábra: iReport 5 11 JasperReports 2. Adatbázis alapú dinamikus riport készítése Adatbázis alapú dinamikus riport készítése Ebben a részben bemutatjuk az adatbázis lekérdezésekre épülő, dinamikus riportkészítés alapjait. Kétféle technikával fogunk megismerkedni Az első az SQL query-t a jrxml fájlba ágyazva mutatja be, mely során bemutatjuk a riportok paraméterezési lehetőségét is. A második a JRDataSource objektumra

épülő megoldás, ahol nincs már szükség a queryString tag-et beágyazni a jrxml állományba. A példákhoz az Informatikai Navigátor 7 számában megismert HSQLDB adatbáziskezelőt fogjuk használni. Vegyük észre, hogy egy természeténél fogva hierarchikus felépítésű riport leírására az XML kiAdatbáziskezelő fejezetten alkalmas eszköz, hiszen gyakorlatilag Tekintettel arra, hogy szükségünk lesz egy adat- abban a szerkezetben tudjuk a jelentés templatebáziskezelőre, indítsuk el a HSQLDB-t szerver et vele elkészíteni, ahogy annak majd ki kell nézmódba, amihez részletes segítséget kapunk az nie. Informatikai Navigátor 7. számából A megismert orszagok táblára épülő select paranccsal A riport szakaszai fogunk dinamikus adatokat szolgáltatni a jelenA következő nagyobb riport szakaszokat részletetésünk részére. sebben az iReport bemutatásánál fogjuk ismertetni, itt csak megemlítjük a szerepüket. JRXML fejlesztés – iReport A

használt fejlesztői környezet A továbbiakban a riport tervezési munkát általában az iReport eszközzel fogjuk végezni, így azt is indítsuk el. Első lépésként frissítjük a csomaggal érkezett HSQLDB jdbc drivert arra a verzióra, amit jelenleg használunk. Ehhez az iReport ToolsOptionsClasspath fülére menjünk Töröljük ki a régi HSQLDB drivert és vegyük fel az általunk használt frissebb hsqldb.jar fájlt Ezután kattintsunk a Report Datasources ikonra és vegyünk fel egy új JDBC kapcsolatot a mi adatbázisunkra. Emlékeztetőül megadjuk szerverünk URL-jét: jdbc:hsqldb:hsql://localhost/xdb (user: SA). Egy JRXML fájl felépítése <title>. A riport címét tartalmazó szakasz, amennyiben használjuk, úgy a riport elejére fog renderelődni. <pageHeader>. Az itt definiált layout minden új oldal elején fog látszódni <columnHeader>. Az oszlopok fejlécének kinézetét tartalmazó specifikációs szakasz. <detail>. Ez a

szakasz minden egyes új adatsor beérkezésekor fog megformálódni <columnFooter>. Az oszlopok láblécének Itt most csak azokat a jrxml elemeket nézzük át, kinézetét tartalmazó specifikációs szakasz. amik a cikkhez szükségesek, a továbbiakat majd a későbbi fejezetekben részletezzük, mindig ah- <pageFooter>. Az itt definiált layout minhoz a témához kötődve, amit éppen ismertetünk den oldal végén fog látszódni 12 JasperReports Adatbázis alapú dinamikus riport készítése <lastPageFooter>. Ugyanaz a szerepe, esetben ez az egyszerű névegyezésen alapuló ilmint a pageFooter elemnek, de azt felváltja az lesztés és értéklekérés működik a field és az dautolsónak generált oldalon, amennyiben ilyen tasource között szakaszt definiálunk. <parameter>. A paraméter a mezőhöz ha<summary> A riport legvégére definiált sonlóan a külvilág és a riportgenerátor közötti szakasz, ami általában összefoglaló

jellegű infor- adatcserét valósítja meg, de a mechanizmus mációkat és végösszegeket tartalmaz. más. Itt az átadandó (kulcs, érték) párokat egy java.utilMap objektum segítségével adjuk át A Nem vizuális elemek jrxml fájlban pedig így definiálunk paramétereket: <field>. A field (mező) szerepe az, hogy a kí<p a r a m e t e r name=" p T e r u l e t " c l a s s=" j a v a l a n g Double " /> p h e a d e r T e r u l e t " c l a s s=" j a v a . l a n g å vülről (adatforrásokból) érkező adatokat össze- <p a r aSmterti enrg "name=" /> rendelje (mapping) a riport elemeihez tartozó A különféle riport elemeken belül az egyes adattartalommal. A mező megadására lássunk paraméterek értékeire $P{.} alakban hivatko2 példát: zunk, ettől eltekintve a használata hasonló a me< f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d

name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> zőkével. Példák: Egy mezőnek ezek szerint van neve és típusa, $P{ p T e r u l e t } vagy $P{ p h e a d e r T e r u l e t } azaz egy befogadó változóként viselkedik. MéAmennyiben a generátor a riport készítése lyebben megnézve ezek mögött a Groovy nyelv során találkozik egy $P{paraméter-név} hivatkoáll, amit az Informatikai Navigátor 5. számában zással, úgy majd tudja, hogy ez egy paraméter részletesebben is bemutattunk. Egy mezőre így lesz, amit a kapott map objektumból tud meglehet hivatkozni: szerezni úgy, hogy annak kulcsa a paraméter-név $F{ORSZAG} vagy $F{NEPESSEG} lesz. A $F azt jelenti, hogy egy mező értékét kérjük. Itt emlékeztetünk arra, hogy a Groovy <property>. A jrxml fájlba bármilyen tet${kifejezés} formája is dinamikusan futtatja az szőleges (kulcs, érték) párt is elhelyezhetünk, ott megadott kódot, azaz

makróhelyettesítés szeazaz ezt nem kívülről kapjuk ebben az esetben. rűen működik. Ez azt jelenti, hogy egy String Példa: típusú változót, mint egy kóddarabot futtat le. <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> Példa, ami a 9-et jeleníti meg a képernyőn: d e f X=" 9 " ; A property értékéhez a JasperReport oszA=" ${X} " p r i n t A; tály statikus getProperty() metódusával férheEz a lehetőség magyarázza meg a field műkö- tünk hozzá. dését, ami összeköti az érkező adatsorok oszlopneveit a riport elemek value (például text) jellemzőivel. Hogy működik mindez? Érkezik egy új adatsor N darab oszloppal. A JasperReports generátor próbálja a riport $F{.} részeit ebből kitölteni. Például veszi a $F{ORSZAG} mezőt és ez alapján próbálja lekérni az adatforrás ORSZAG nevű oszlopát (vagy adatát). A legtöbb <variable>. A változók segítségével

egyszerűbbé tehetjük a riport tervét, illetve segítségével gyűjthetünk különféle értékeket, amiket a jelentés alkalmas helyein megjeleníthetünk < v a r i a b l e name=" QuantitySum " c l a s s=" j a v a . l a n g Double " c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n>$F{ Q u a n t i t y }</ v a r i a b l e E x p r e s s i o n å > </ v a r i a b l e> 13 JasperReports A fenti példa változójának értékére a $V{QuantitySum} formával hivatkozhatunk, amikor azt egy olyan helyre tesszük a jrxml-ben, ahol arra szükség van. A változó kifejezés megadásánál hivatkozhatunk más, értékkel bíró riport elemekre, így akár más változókra is Fontos fogalom a változók reinicializálása, azaz mikor kapnak újra kezdőértéket Az alapértelmezett a report szint, ami azt jelenti, hogy egy alkalommal, a riportgenerálás kezdetekor kapnak csak kezdőértéket és kiszámításuk a

jelentés végének elérésekor lesz komplett. Természetesen választhatunk alacsonyabb szintet is a reinicializáláshoz, nézzük meg ezeket: Adatbázis alapú dinamikus riport készítése • Average A számot adó kifejezés értékek számtani átlagát számolja. • Lowest A legkisebb érték. • Highest A legnagyobb érték. • Standard Deviation A standard szórás. • Variance A szórásnégyzet. • System Saját készítésű algoritmus. • First Az első kiszámított érték. • page a változó minden lapkezdéskor nul- A változók működésének további lényeges jellázódik. lemzője az Increment Type, azaz itt – ellentétben a reset-tel – azt határozzuk meg, hogy mihez van • column minden új oszlopnál reset törkötve a halmozás: ténik. • group a megadott csoport váltásakor nullázódik, így itt gyűjthető a csoportra jellemző aggregált mennyiség. • Report A változó csak 1 alkalommal halmozódik, amikor a riport

végéhez ér a generátor. • none soha nincs reset. • Page Az inkrementálás minden lap befejezéskor történik. A következő példában a page szint megadását láthatjuk, ami egy új lapra ugráskor nullázódik és a végén lesz komplett a kiszámítása. < v a r i a b l e name=" QuantitySum " c l a s s=" j a v a . l a n g Double " r e s e t T y p e=" Page " c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n>$F{ Q u a n t i t y }</ v a r i a b l e E x p r e s s i o n å > < i n i t i a l V a l u e E x p r e s s i o n>new Double ( 0 ) </å i n i t i a l V a l u e E x p r e s s i o n> </ v a r i a b l e> A calculation attribútum azt határozza meg, hogy az aggregálás mi legyen: • Count Ennyiszer történt kalkuláció, azaz a nem null értékek száma. • Column Az inkrementálás minden oszlop befejezéskor történik. • Group A csoportok kezelését a külön

cikkben ismertetjük. • None Minden egyes új rekorddal halmozódik a változó. <queryString>. Amennyiben a jrxml-be • Distinct Count Ugyanaz, mint az előző, szeretnénk beágyazni azt az SQL selectet, ami de a csak a különböző értékeket veszi bele az adatsorokat hozza, úgy így tehetjük meg: az összegbe. <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> • Sum A variableExpression kifejezésekből kapott értékeket itt összeadja a váltoTermészetesen a field nevek ilyenkor az SQL zóba. select eredményhalmaz oszlopnevei lesznek. 14 JasperReports Adatbázis alapú dinamikus riport készítése <import>. A jrxml fájlban gyakran hivatko- egyszerű jelentést Itt tehát az adatainkat már zunk java osztályokra, így ezeket be kell impor- egy valódi adatbázisból fogjuk nyerni. tálni. Például, ha egy Date objektumot szeretnénk használni egy field értékeként,

akkor erre szükség lesz: <i m p o r t v a l u e=" j a v a . u t i l Date " /> Ekkor ennek használata egy textField vizuális jrxml komponensen belül: <t e x t F i e l d E x p r e s s i o n c l a s s=" j a v a . u t i l Date ">< ! [CDATA[ å new Date ( ) ] ] ></ t e x t F i e l d E x p r e s s i o n> <group>. Az adatsorok többszintű csoportosításának (összegfokozatos lista) definiálását teszi lehetővé Használatának bemutatását a későbbiekben láthatjuk majd Vizuális JRXML címkék A következő fejezetekben még sok jrxml elemet fogunk bemutatni, ami a szövegeket, képeket, grafikonokat és egyéb lehetőségeket valósítják meg. Itt most ezekből csak az ebben a cikkben használt 2 komponenst mutatjuk be, de azt is csak érintőlegesen, hiszen a beállítási lehetőségeiket (stílusok, méretek, stb.) úgyis az iReport segítségével érdemes manipulálni Szeretnénk ki- 21 ábra: A riport query vizuális

megtervezése emelni a reportElement címkét, ami a vizuális komponensek megadásánál mindig előfordul és Hozzunk létre az iReport segítségével egy új annak geometriai kiterjedését és pozícióját adja riportot és legyen a neve: Orszagok.jrxml A meg. 2.1 ábra az iReport Report Query eszköze, ahol kiválasztottuk a korábban már létrehozott <staticText>. Egy riportba épített szöveges HSQLDB Connection-t és megadtuk a s e l e c t ∗ from o r s z a g o k elem, amit utólag már nem lehet változtatni. SQL lekérdezést. A képen látható minden más részlet ezután már automatikusan állító<textField>. Egy riportba épített szöveges elem, amit utólag is lehet változtatni, így az elő- dott össze. Alul láthatjuk a select várható eredményét, középen pedig az adatbázis oszlopait, zőnél sokkal rugalmasabb a használata. amikből ezek a field sorok automatikusan bekerülnek a jrxml fájlba: A példa riport megtervezése < f i e l d

name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> A feladat az, hogy a HSQLDB adatbázisban ta- Nyomjuk meg az OK gombot, amivel visszatélálható orszagok táblára építve készítsünk egy rünk az tervező felületre, amit a 2.2 ábra mutat 15 JasperReports Adatbázis alapú dinamikus riport készítése 2.2 ábra: iReport - Orszagokjrxml tervezése Nézzük át az iReport azon ablakait, amikre ebben a példában szükségünk lesz! A baloldali Report inspector feladata, hogy a JRXML fájl szerkezetét, az abban lévő komponenseket mutassa, ott navigálhassunk. Látjuk a riportok főbb szakaszait Amennyiben kinyitnánk a Fields ágat, látnánk azokat az automatikusan generált field elemeket, amik a select megadásakor jöttek létre. Mindezt kézzel is megírhatnánk, de az iReport igazán remek eszköz, hogy ebben a maximális támogatást adja nekünk. Az ábra közepe a tervező vásznat mutatja, ami esetünkben nem túl összetett

kiépítésű, az ott látottakat már mi tettük fel oda. Nézzük meg sorjában őket! • A Title részbe csak egy konstans staticText szöveget tettünk: Az országok legfontosabb adatai. Ez – ahogy már említettük – a ri16 port elején, 1 alkalommal fog megjelenni. A működését sokféleképpen szabályozhatjuk, például mondhatnánk, hogy ez a szekció egy külön, első oldalon jelenjen meg. • A Page Header is rendkívül egyszerű, hatására a piros Titkos! szöveget minden oldalon látni fogjuk a lap tetején. • A lehetséges mezőkből most csak 4 darabot helyeztünk el a Detail sávba, a nekik megfelelő oszlopneveket pedig a Column Header részbe. A detail az a rész, ahol a beérkező adatsorok egymás alatt jelennek majd meg, persze lapváltás szükséges lesz, hiszen, ahogy látjuk majd a jelentésünk 14 oldalas lesz. • Utoljára még a Page Footer területre tet- JasperReports tük az oldalszámozást, aktuális oldal/összes oldal alakra

formázva. Mindkét értéket az előre definiált PAGE NUMBER változó adja, de az eltérő kiértékelési időpont miatt jól működik az értékének a használata. Adatbázis alapú dinamikus riport készítése van fókuszban, így annak beállítható jellemzőinek egy része látható. A jobb oldali ablakrészlet pedig a komponens palettát mutatja, azaz drag’n’drop módszerrel innen is feltehetünk elemeket a riportra. 2. XML: Ez maga a JRXML fájl, amit 2-útas módon (azaz utána látszik a vizuális felületen is) itt is szerkeszthetünk, tartalmát a 2-1. Programlistán tanulmányozhatjuk 3. Preview : Itt tekinthetjük meg, hogy élőben milyen lesz a kinézete a jelentésünknek A funkciója azonos a más ismert ant viewDesignXML paranccsal. Ennyi előzmény után láthattuk, hogy a kézzel is elkészíthető Orszagok.jrxml fájlt milyen módon állítottuk elő pár perc alatt az iReport segítségével. Most nézzük meg egy kicsit alaposabban is a 2-1.

Programlista tartalmát! Az első fontos rész a 8-10 sorok között látható, ahol megérthetjük a riportba ágyazott select, azaz a queryString tag megadási formátumát. A 11-26 sorok között mezőket találunk, amik a select alapján automatikusan jöttek létre, de mi ebből a riportban csak az első 4-et használjuk, azaz drag’n’droppal ezeket helyeztük el a vászonra. A background címkét (27-29 sorok) nem állítottuk be, de itt adhatnánk meg például vízjelet is A 30-40 sorok közötti title tag már ismerős, az ő sávja (band ) most éppen 79 px méretű, egyetlen eleme egy staticText, aminek 3 jellemzője van most explicite beállítva: 2.3 ábra: Riport tervezési elemek 1. reportElement: A staticText méreteit és pozícióját határozza meg a sávhoz képest relatív módon. Vegyük észre, hogy a tervező nézet a következő 3 módon tudja megmutatni a JRXML fájlt: 2. textElement: Jelenleg csak a használt betű mérete tér el a default

értéktől, hiszen ezt 24 px értékre állítottuk a tervezés során. 3. text: Az ismert cím szövege 1. Designer : Itt történik a vizuális tervezés, amihez a 2.3 ábra eszközeit is használhat- A 41-83 sorokban lévő pageHeader és columnjuk Az ábrán éppen az ORSZAG mező Header felépítése a title-hoz hasonló, szerepüket 17 JasperReports Adatbázis alapú dinamikus riport készítése ismerjük. A 84-107 sorok nagyon fontosak, hitartalmazza azt a mezőt, ami az adatbászen a külső adatforrásból érkező sorok oszlopait zis oszlopával való névegyezésen alapszik itt határozzuk meg, ez valójában a 85-106 sorok és értékét $F{ORSZAG} alakban érjük el. közötti band tartalmát jelenti. A sávra 4 darab textField komponenst tettünk, amelyek kö- A 111-124 sorokban lévő pageFooter -t már ismerjük, jelenleg ez a sáv csak az oldalszámozül például az ORSZAG így néz ki: zás megjelenítésére szolgál. Itt most csak a 118 1. reportElement: A

textField méreteit és po- sorban lévő textField evaluationTime="Report" zícióját határozza meg a sávhoz képest re- attribútumára hívnánk fel a figyelmet, ugyanis erre a mezőre megadtuk, hogy akkor fusson le latív módon. rá a kiértékelés, ha elkészült a teljes riport. Ez 2. textFieldExpression: A 89 sorban végre logikus is, hiszen csak akkor tudható meg az is, megérthetjük, hogy egy textField hogyan hogy hány oldalas lett. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 < !−− 2−1. P r o g r a m l i s t a : Orszagok j r x m l −−> <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www å w3 . o r g /2001/XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i

o n=" h t t p : // j a s p e r r e p o r t s s o u r c e f o r g e n e t /å j a s p e r r e p o r t s ␣ h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok " å l a n g u a g e=" groovy " pageWidth=" 595 " p a g e H e i g h t=" 842 " columnWidth=" 555 " l e f t M a r g i n=" 20 " å r i g h t M a r g i n=" 20 " topMargin=" 20 " bottomMargin=" 20 " uuid=" 9 a1dbe76 −1ae5 −4418−9e43−e 5 6 f 6 e d 9 8 1 9 3 å "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x" v a l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y" v a l u e=" 0 " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n

g> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math BigDecimal " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g

S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> <background> <band s p l i t T y p e=" S t r e t c h " /> </ background> < t i t l e> <band h e i g h t=" 79 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" b4880372−f0bd −40c2 −98d9−9 f 0 f e 4 3 3 d c 2 1 " x=" 55å "

y=" 14 " width=" 405 " h e i g h t=" 31 " /> <t e x t E l e m e n t> <f o n t s i z e=" 24 " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Az o r s z á g o k l e g f o n t o s a b b a d a t a i ] ] ></ t e x t> </ s t a t i c T e x t> 18 JasperReports 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 Adatbázis alapú dinamikus riport készítése </ band> </ t i t l e> <pageHeader> <band h e i g h t=" 35 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" d eb 8 1 fe d −e 3 4 f −4bd0−ae94 −0508 a f 0 9 f f 2 5 " x="å 444 " y=" 0 " width=" 100 " h e i g h t=" 20 " f o r e c o l o r="#FF0066" /> <t e x t E l

e m e n t t e x t A l i g n m e n t=" Right "> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ T i t k o s ! ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ pageHeader> <columnHeader> <band h e i g h t=" 42 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" c e 8 a 1 1 b f −2f 1 1 −474c−bb67−6e 8 8 0 2 7 5 2 4 5 8 " x=" 24å " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Ország ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" 491 c f 4 f 0 −eeaa −4d9e −909a−8e e 4 9 5 1 8 b 2 4 e " x="å 142 "

y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Főváros ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" f f 2 e f e e a −6633−4b8a−8a04 −9328 b0ac56da " x="å 261 " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ F ö l d r é s z ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" d 4 f 1 c d a c −91ac −494 f −a013 −21 e37d30e2d4 " x="å 379 " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e

x t A l i g n m e n t=" Right "> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ T e r ü l e t (km2) ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ columnHeader> < d e t a i l> <band h e i g h t=" 40 " s p l i t T y p e=" S t r e t c h "> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" a2856d02 −9 c e f −48e3 −9240− c f 0 a 1 1 b 7 6 4 8 8 " x=" 24å " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{ORSZAG} ] ] ></ t e x t F i e l d E x p r e s s i o n å > </ t e x t F i e l d> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 5 e 6 f f 3 5 e −58db−418b−9bcb−e 4 f 4 0 4 4 1 8 5 e 0 " x="å 142 " y=" 12 "

width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOVAROS} ] ] ></å t e x t F i e l d E x p r e s s i o n> 19 JasperReports 95 96 97 </ t e x t F i e l d> <t e x t F i e l d i s S t r e t c h W i t h O v e r f l o w=" t r u e "> <r e p o r t E l e m e n t uuid=" be169129 −86a9 −47c3 −829a −4196 d e c f 2 7 1 c " x="å 261 " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOLDR HELY} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" a583d337 −91a5−4ee2−b 1 c f −3b c d 4 5 4 2 9 f 8 a " x="å 379 " y=" 12 " width=" 100 " h e i g h t=" 20 "

/> <t e x t E l e m e n t t e x t A l i g n m e n t=" Right " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{TERULET} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 Adatbázis alapú dinamikus riport készítése </ band> </ d e t a i l> <columnFooter> <band h e i g h t=" 45 " s p l i t T y p e=" S t r e t c h " /> </ columnFooter> <p a g e F o o t e r> <band h e i g h t=" 54 " s p l i t T y p e=" S t r e t c h "> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 238 f 2 d f b −d246 −46b7−97b1−90 f b d f 7 d 8 6 9 e " x="å 241 " y=" 19 " width=" 80 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t="

Right " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{PAGE NUMBER}+" /" ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <t e x t F i e l d e v a l u a t i o n T i m e=" Report "> <r e p o r t E l e m e n t uuid=" 45046766 −1 c1b −4a3b −8380−9 e c 2 6 8 d 6 f 7 d f " x="å 331 " y=" 19 " width=" 40 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{PAGE NUMBER} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ p a g e F o o t e r> <summary> <band h e i g h t=" 42 " s p l i t T y p e=" S t r e t c h " /> </summary> </ j a s p e r R e p o r t> A riport elkészítése és megtekintése nek. Az első az, hogy a korábban megismert Elkészült az első, adatbázis

select-re épülő riport tervünk, azaz rendelkezünk egy jó Orszagok.jrxml fájllal A következő teendőket az 1. cikkben már lényegében ismertettük, bár az adatbázis kapcsolat miatt újszerű elemek is lesz1 2 3 4 5 6 7 8 // 2−2. P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; import j a v a . s q l C o n n e c t i o n ; import j a v a . u t i l HashMap ; . public c l a s s JRHelper 20 JRHelper class makeReport() metódusának elkészítettük azt a változatát, ami a 3. paraméterben egy javasqlConnection objektumot vár (2-2. Programlista) A megvalósításnál a fillReportToFile() metódusnak is ezt a változatát használtuk (13. sor) JasperReports 9 10 11 12 13 14 15 16 { . . } Adatbázis alapú dinamikus riport készítése public void makeReport ( S t r i n g j a s p e r F i l e N a m e , HashMap params , C o n n e c t i o n conn ) throws å JRException { J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j

a s p e r F i l e N a m e , params , conn ) ; } szagok értékre, majd adjuk ki az ant compile parancsot, ami létrehozza az Orszagok.jasper fájlt A 2.4 ábra a riport tervet az ant viewDesignXML utasítással mutatja meg, azonban a továbbiakban ezt nem fogjuk használni, hiszen erre az iReport alapvetően alkalmas. A TestOrszagokRiport osztály (2-3. Programlista) feladata, hogy segítségével elkészíthessük az Orszagokjrprint jelentést A 20 sorban szerzünk egy adatbázis kapcsolatot a HSQLDB szerver felé, majd a 22. sorban a JRHelper új makeReport() metódusával létrehozzuk a ripor2.4 ábra: A Design megtekintése tot. A 2 paraméter egy Map, amit most 0 darab elemmel adunk át, szerepét a következő pontban Még nem fordítottuk le a jrxml fájlt jasper ismertetjük. A programot lefuttatva és az ant binárisra, így legyen ez a következő lépés. Az ant view parancsot használva a 25 ábrán mutatott build.xml -ben a filename értékét állítsuk be Or- riport

készül el 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 // 2−3. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; import import import import java . java . java . java . s q l . Connection ; s q l . DriverManager ; s q l . SQLException ; u t i l . HashMap ; public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j a s p e r " ; } public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , å "" ) ; JRHelper j h = new JRHelper ( ) ; j h . makeReport ( j a s p e r F i l e , new HashMap ( ) , conn ) ; conn . c l o s e ( ) ; } 21 JasperReports Adatbázis alapú dinamikus riport készítése

Paraméterek használata Ebben a pontban bemutatjuk, hogy a queryString elem értékét hogyan tudjuk dinamikusan változtatni, amihez azt erre fogjuk cserélni: s e l e c t ∗ from o r s z a g o k where t e r u l e t < $P{ p T e r u l e t } A példában 2 riport paramétert fogunk használni, amiket az iReport Report inspector Parameters ágán tudunk könnyen a jrxml-hez adni, őket a 2-4. Programlista 5 és 6 sora mutatja Az egyes paraméterek szerepe ez lesz: 2.5 ábra: Az elkészült riport megtekintése • pTerulet: Ahogy látható, ez részévé vált a queryString select utasításnak (9. sor), így tudjuk majd azt manipulálni. • pheaderTerulet: Ez csak egy próba arra, hogy a columnHeader utolsó oszlopának a nevét paraméterként adjuk át a jelentés generátorának (18. sor) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 < !−− 2−4. P r o g r a m l i s t a : Orszagok j r x m l −−> <?xml version=" 1 . 0 " e n c o d i n

g="UTF−8" ?> . <p a r a m e t e r name=" p T e r u l e t " c l a s s=" j a v a . l a n g Double " /> <p a r a m e t e r name=" p h e a d e r T e r u l e t " c l a s s=" j a v a . l a n g S t r i n g " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where t e r u l e t < $P{ p T e r u l e t } ] ] > </ q u e r y S t r i n g> . < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> 17 18 19 20 21 22 23 </ band> </ columnHeader> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 8 a 1 9 8 f 6 f −fbde −4b87 −9604− a 9 c d f f 6 1 d d 9 7 " x="å 411 " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n

t=" Right " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ P{ p h e a d e r T e r u l e t } ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> . </ j a s p e r R e p o r t> Az új jrxml-hez is generáljunk jasper fájlt, majd tekintsük a TestOrszagokRiport új változatát (2-5. Programlista) A 20-21 sorokat már ismerjük, az újdonság most jön. A 23 sorban 22 létrehozunk egy params nevű HashMap objektumot, majd a következő 2 sorban 2 elemet teszünk bele, amik a paraméterek nevei és értékei, majd a 27. sorban már ezzel felszerelve hívjuk a JasperReports Adatbázis alapú dinamikus riport készítése korábbi makeReport()-ot. A jelentés generálója egyaránt Az új where feltétel miatt riportunk ahány alkalommal találkozik egy $P{.} hivat- most 7 oldalasra csökkent A 4 oszlop neve kozással, mindig innen próbálja annak az értékét pedig a paraméterként átadott Area lett.

feloldani. Ez igaz a select-re, de a 4 oszlopnévre 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 // 2−5. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; import import import import java . java . java . java . s q l . Connection ; s q l . DriverManager ; s q l . SQLException ; u t i l . HashMap ; /∗ ∗ ∗ ∗ @author i n y i r i ∗/ public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j a s p e r " ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , å "" ) ; JRHelper j h = new JRHelper ( ) ; HashMap params = new HashMap ( ) ; params . put ( " p

T e r u l e t " , 1 0 0 0 0 0 0 0 ) ; params . put ( " p h e a d e r T e r u l e t " , " Area " ) ; } } j h . makeReport ( j a s p e r F i l e , params , conn ) ; conn . c l o s e ( ) ; A queryString helyett adatforrás A 2. fejezet befejezéseként vetünk egy pillantást a JasperReports adatforrások használatára, ugyanis nem feltétlenül szükséges a queryStringet a jrxml-be tennünk. A szemléltető példánk az előző marad, ugyanazt a feladatot fogjuk megol1 2 3 4 5 6 7 8 dani, de immár datasource használatával. Ehhez az első lépés az, hogy a teljes queryString részt, illetve az ahhoz kapcsolódó pTerulet paramétert kivesszük a jrxml fájlból, amit az egyértelműség érdekében ismét teljes terjedelmében tartalmaz a 2-6. Programlista < !−− 2−6. P r o g r a m l i s t a : Orszagok j r x m l −−> <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns="

h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www å w3 . o r g /2001/XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s s o u r c e f o r g e n e t /å j a s p e r r e p o r t s ␣ h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok " å l a n g u a g e=" groovy " pageWidth=" 595 " p a g e H e i g h t=" 842 " columnWidth=" 555 " l e f t M a r g i n=" 20 " å r i g h t M a r g i n=" 20 " topMargin=" 20 " bottomMargin=" 20 " uuid=" 9 a1dbe76 −1ae5 −4418−9e43−e 5 6 f 6 e d 9 8 1 9 3 å "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x" v a

l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y" v a l u e=" 0 " /> 23 JasperReports 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 Adatbázis alapú dinamikus riport készítése <p a r a m e t e r name=" p h e a d e r T e r u l e t " c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math BigDecimal " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r "

/> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t

e g e r " /> <background> <band s p l i t T y p e=" S t r e t c h " /> </ background> < t i t l e> <band h e i g h t=" 79 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" b4880372−f0bd −40c2 −98d9−9 f 0 f e 4 3 3 d c 2 1 " x=" 55å " y=" 14 " width=" 405 " h e i g h t=" 31 " /> <t e x t E l e m e n t> <f o n t s i z e=" 24 " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Az o r s z á g o k l e g f o n t o s a b b a d a t a i ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ t i t l e> <pageHeader> <band h e i g h t=" 35 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" d eb 8 1 fe d −e 3 4 f −4bd0−ae94 −0508 a f 0 9 f f 2 5 "

x="å 444 " y=" 0 " width=" 100 " h e i g h t=" 20 " f o r e c o l o r="#FF0066" /> <t e x t E l e m e n t t e x t A l i g n m e n t=" Right "> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ T i t k o s ! ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ pageHeader> <columnHeader> <band h e i g h t=" 42 " s p l i t T y p e=" S t r e t c h "> <s t a t i c T e x t> <r e p o r t E l e m e n t uuid=" c e 8 a 1 1 b f −2f 1 1 −474c−bb67−6e 8 8 0 2 7 5 2 4 5 8 " x=" 24å " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Ország ] ] ></ t e x t> </ s t a t i c T e x t> <s t a

t i c T e x t> <r e p o r t E l e m e n t uuid=" 491 c f 4 f 0 −eeaa −4d9e −909a−8e e 4 9 5 1 8 b 2 4 e " x="å 142 " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ Főváros ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 24 JasperReports 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 Adatbázis alapú dinamikus riport készítése <r e p o r t E l e m e n t uuid=" f f 2 e f e e a −6633−4b8a−8a04 −9328 b0ac56da " x="å 261 " y=" 0 " width=" 100 " h e i g h

t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t>< ! [CDATA[ F ö l d r é s z ] ] ></ t e x t> </ s t a t i c T e x t> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 8 a 1 9 8 f 6 f −fbde −4b87 −9604− a 9 c d f f 6 1 d d 9 7 " x="å 379 " y=" 0 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" Right "> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ P{ p h e a d e r T e r u l e t } ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ columnHeader> < d e t a i l> <band h e i g h t=" 40 " s p l i t T y p e=" S t r e t c h "> <t e x t F i e l d>

<r e p o r t E l e m e n t uuid=" a2856d02 −9 c e f −48e3 −9240− c f 0 a 1 1 b 7 6 4 8 8 " x=" 24å " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{ORSZAG} ] ] ></ t e x t F i e l d E x p r e s s i o n å > </ t e x t F i e l d> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 5 e 6 f f 3 5 e −58db−418b−9bcb−e 4 f 4 0 4 4 1 8 5 e 0 " x="å 142 " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOVAROS} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <t e x t F i e l d i s S t r e t c h W i t h O v e r f l o w=" t r u e "> <r e p o r t E l e m e n t uuid=" be169129 −86a9 −47c3 −829a

−4196 d e c f 2 7 1 c " x="å 261 " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOLDR HELY} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" a583d337 −91a5−4ee2−b 1 c f −3b c d 4 5 4 2 9 f 8 a " x="å 379 " y=" 12 " width=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" Right " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{TERULET} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ d e t a i l> <columnFooter> <band h e i g h t=" 45 " s p l i t T y p e=" S t r e t c h " /> </ columnFooter> <p a g e F o o t e r>

<band h e i g h t=" 54 " s p l i t T y p e=" S t r e t c h "> <t e x t F i e l d> <r e p o r t E l e m e n t uuid=" 238 f 2 d f b −d246 −46b7−97b1−90 f b d f 7 d 8 6 9 e " x="å 241 " y=" 19 " width=" 80 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" Right " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{PAGE NUMBER}+" /" ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <t e x t F i e l d e v a l u a t i o n T i m e=" Report "> <r e p o r t E l e m e n t uuid=" 45046766 −1 c1b −4a3b −8380−9 e c 2 6 8 d 6 f 7 d f " x="å 331 " y=" 19 " width=" 40 " h e i g h t=" 20 " /> 25 JasperReports 120 121 122 123 124 125 126 127 128 Adatbázis alapú dinamikus riport készítése <t e x t E l e m e n t />

<t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{PAGE NUMBER} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ p a g e F o o t e r> <summary> <band h e i g h t=" 42 " s p l i t T y p e=" S t r e t c h " /> </summary> </ j a s p e r R e p o r t> A jrxml más tekintetben nem változott, így annak rövid elemzésétől most eltekintünk, azonban a jrxml jasper fordítást elvégezzük. A keletkezett új Orszagokjasper binárisra elkészítettük a TestOrszagokRiport 3 változatát (2-7 Programlista). Ez már a JRDataSource interfésszel rendelkező adattermelő objektumra épül A 20. sor mutatja – mint eddig is –, hogy milyen jasper fájlt fogunk használni A 24 sor az ismerős select-ünk, ahol a ’ ?’ a kihagyott pTerulet paraméter helyett lesz használatos, hogy még hasonlóbb legyen a megoldás az előzőéhez. A 26 sorban az ismerős módon szerzünk egy

adatbázis Connection objektumot, de itt nem ezt fogjuk átadni a riport generátorának, ami lényeges 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 különbség. A 27-29 sorok között megadjuk a paramétert (értéke: 10000000), majd lefuttatjuk a select-et, ami visszaad egy szabványos rs nevű ResultSet objektumot. És a 31 sorban érkezik az igazi újdonság! Az rs-t becsomagoljuk egy JRDataSource interfésszel bíró jrds nevű objektumba, ami most történetesen egy JRResultSetDataSource class példány. A 38 sorban megadjuk az egyetlen riport paraméterünket, aminek értéke most a pontosabb Area (km2) szöveg lett. A 40 sorban találkozunk a 2 jelentős változtatással, ugyanis itt újra azt a makeReport() metódust használtuk, amit az 1. cikkben megismertünk, hiszen az alkalmas egy JRDataSource fogadására. // 2−7. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a ( JRDataSource ) package o r g . c s t e s t ; import

import import import import import import import java . s q l Connection ; j a v a . s q l DriverManager ; java . s q l PreparedStatement ; java . s q l ResultSet ; j a v a . s q l SQLException ; j a v a . u t i l HashMap ; n e t . s f j a s p e r r e p o r t s e n g i n e JRDataSource ; net . s f j a s p e r r e p o r t s engine JRResultSetDataSource ; /∗ ∗ ∗ ∗ @author i n y i r i ∗/ public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j a s p e r " ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { S t r i n g s q l = " s e l e c t ␣ ∗ ␣ from ␣ o r s z a g o k ␣ where ␣ t e r u l e t ␣<␣ ? " ; C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , å

"" ) ; P r e p a r e d S t a t e m e n t stmt = conn . p r e p a r e S t a t e m e n t ( s q l ) ; 27 26 JasperReports 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 Adatbázis alapú dinamikus riport készítése stmt . s e t D o u b l e ( 1 , 1 0 0 0 0 0 0 0 ) ; R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ) ; JRDataSource j r d s = new J R R e s u l t S e t D a t a S o u r c e ( r s ) ; JRHelper j h = new JRHelper ( ) ; HashMap params = new HashMap ( ) ; // params . p u t (" p T e r u l e t " , 1 0 0 0 0 0 0 0 ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; j h . makeReport ( j a s p e r F i l e , params , j r d s ) ; rs . close () ; stmt . c l o s e ( ) ; conn . c l o s e ( ) ; } } A programot futtassuk le és nézzük meg a keletkezett Orszagok.jrprint tartalmát az ant view paranccsal! Leszámítva a 4. oszlop kissé megváltoztatott nevét, ugyanazt a 7 oldalt fogjuk

látni, mint korábban. A JRResultSetDataSource pontosan úgy működik, ahogy vártuk. Ő is egy select-re épül, így az eredménytábla oszlopneveit hasonlóan illeszteni lehet a jrxml-be lévő fieldekre. A JasperFillManager Végezetül szeretnénk pár szót szólni JasperFillManager fillReportToFile() metódusának lehetőségeiről. Ez a metódus többszörösen túlterhelt, de mindegyik funkciója a jrprint fájl elkészítését szolgálja A későbbiekben látni fogjuk, hogy a riportot nem szükséges fájlba mentenünk, az lehet például egy OutputStream is. A fájlba gyártó metódus lehetséges paraméterei ezek lehetnek: • JasperReport: A lefordított jrprint tarta- lom memóriabeli reprezentációja. Bizonyos körülmények között használatos, de nem ez a tipikus. • Connection: Egy java.sqlConnection objektum, amikor beágyazott query-re épül a riportkészítés. • JRDataSource: Az utolsó példában látott adatforrás alapú riportkészítésnél

használatos. • parameters: Egy java.utilHashMap, ami lehetővé teszi a riport paramétereinek átadását. • sourceFileName: A JasperReport objektum alternatívája, amikor jrprint fájl nevet adunk át a riport készítéséhez. • destFileName: A legyártott jrprint fájl neve lesz. Amennyiben nem adjuk meg, úgy a jasper fájl nevével, de jrprint kiterjesztéssel generálódik majd a riport. 27 JasperReports 3. A JasperReports adatforrások használata A JasperReports adatforrások használata Az előző rész végén már megismerhettük az adatforrás használatát. Ez azonban egy sokkal általánosabb JasperReports lehetőség, hiszen minden olyan objektum lehet egy riport adatforrása, ami implementálja a JRDataSource interfészt. Ez a gyakorlatban szinte a végtelen lehetőségek tárházát jelenti, amikor jelentésünket adatokkal töltjük fel. Egy jól kitalált adatforrás objektum több helyről és meglehetősen összetett logikával képes táplálni

az elkészítendő dokumentumunkat. // 3−1. P r o g r a m l i s t a : JRDataSource j a v a package n e t . s f j a s p e r r e p o r t s e n g i n e ; public i n t e r f a c e JRDataSource { /∗ ∗ ∗ T r i e s t o p o s i t i o n t h e c u r s o r on t h e n e x t e l e m e n t i n t h e d a t a s o u r c e . ∗ @return t r u e i f t h e r e i s a n e x t r e c o r d , f a l s e o t h e r w i s e ∗ @throws JRException i f any e r r o r o c c u r s w h i l e t r y i n g t o move t o t h e n e x t e l e m e n t ∗/ public boolean n e x t ( ) throws JRException ; } /∗ ∗ ∗ Gets t h e f i e l d v a l u e f o r t h e c u r r e n t p o s i t i o n . ∗ @return an o b j e c t c o n t a i n i n g t h e f i e l d v a l u e . The o b j e c t t y p e must be t h e f i e l d å object type . ∗/ public O b j e c t g e t F i e l d V a l u e ( JRField j r F i e l d ) throws JRException ; A JasperReports adatforrás Egy JasperReports adatforrás bármilyen objektum lehet, ami

implementálja a JRDataSource interfészt (3-1. Programlista), aminek 2 metódusa van: next() és getFieldValue() Egyik sem okozhat különösebb meglepetést azzal, amit a működésüktől elvárunk, amikor egy osztály implementálja őket. A next() a következő sorra próbálja pozicionálni az adatforrást, ha ez sikerül akkor true, különben false értéket ad vissza. Ez lehetővé teszi, hogy a háttérben működő és a next() metódust visszahívó riportgenerátor működése megfelelően legyen vezérelve. A getFieldValue() metódust szintén a generátor hívja és 2 körülmény mindig igaz: 2. A JRField paramétert a generátor úgy állítja össze, hogy veszi az éppen aktuális $F{field-name} jrxml -beli hivatkozást és ebből egy ilyen típusú objektumot gyárt le, ezt átadva a getFieldValue() metódusnak, ami persze alkalmas módon van elkészítve. Ez azt jelenti, hogy a jrField objektum aktuális sorra való alkalmazása alapján kiválasztódik a

visszaadandó érték. Létezik egy származtatott adatforrás interface is, a JRRewindableDataSource, ahol a moveFirst() metódus implementálása is szükséges. Ezzel az adatforrás elejére tudunk „visszatekerni”. Az üres adatforrás 1. A hívás mindig az adatforrás aktuális so- Az 1-4 Programlista JRHelper teszt programjárára vonatkozik nál már megismertük JREmptyDataSource class 28 JasperReports szerepét. Felmerül a kérdés, hogy erre miért is van szükség? A riportot készítő JasperFillManager osztály többféleképpen is lehetővé teszi a natív jrprint riport fájlok elkészítését. Ezek a metódusok az alábbi 3 típusba sorolhatóak: • fillReportToFile(.) Ekkor a jrprint dokumentum egy külső fájlba készül (eddig mindig ezt a lehetőséget használtuk példáinkban). • fillReport(.) Ez a metódus egy JasperPrint objektumot ad vissza, ami a jrprint objektum modelljét jelentő osztály. A JasperReports adatforrások használata A java

Map alapú adatforrás Amikor a 2. cikkben megismertük az SQL select alapú eredménytáblát, láthattuk hogy az oszlopok és a jrxml fájlban megadott mezők (field) nevének illeszkedése milyen természetes eleganciával működött. A Map típusú adatforrás is pont ehhez hasonló. Egy adatforrás sor nem más, mint egy Map objektum, ahol (kulcs, érték) párok vannak. A kulcs, mint név van abban a szerepben, mint a select eredményének oszlop neve. Az adatforrás azonban több sorból áll, amit az alábbi 2 módszerrel is utánozni tudunk: • a Map objektumok tömbje • fillToStream(.) A jrprint dokumen• a Map objektumok kollekciója (például tumot OutputStream objektumként adja láncolt lista) vissza, ezzel a módszerrel például egy Java Ebben a modellben már elkészíthető egy JRservlet választ tudunk generálni. DataSource interfésszel rendelkező class, ahol az Korábban már említettük, hogy ezek a fill.() egyes metódusok így tudnak működni:

metódusok 3 input információt mindig kötele• next() Értelmezhető a tömb következő zően kapnak: indexű elemeként, mely ha még van, akkor 1. A riport template külső jasper fájlként a visszatérési érték true, különben false. vagy a memóriában már felépített Jasper• getFieldValue() A jrxml field aktuális Report objektumként megadva. sorra vonatkozó feltöltésekor a generátor 2. A riport paraméterei, ami egy Java Map megszerzi a mező nevét (legyen ez most objektum. fieldName) és ezt használja fel az érték előállításához egy get(fieldName) hívással. 3. A riport dinamikus adatai, ami egy SQL Azt is fontos észben tartani, hogy a mező Connection vagy JRDataSource objektum típusos, hiszen a neve mellett az osztálya közreműködésével szerezhető meg a fill.() is meghatározásra került, így a generátor számára. a megszerzett értéket esetleg még erre a Ennyi elmélet után képzeljünk el egy olyan riclass-ra át is konvertálja.

portot, ami valójában nem tartalmaz semmilyen A 3-2. Programlista a Map adatforrás hasznáadatforrásból érkező adatot sem Ilyen lehet péllatát mutatja be, miközben az adatbázis alapú dául egy nyomtatvány vagy számla. Ugyanakkor példánál használt és ott lefordított jasper fájlt formálisan itt is szükséges egy adatforrás, így nem is változtattuk meg. Ezzel az is látható, ezekben a helyzetekben mindig egy JREmptyhogy amennyiben egy jrxml /jasper pároshoz ilDataSource objektumot használunk. A keletkeleszkedő adatforrásról gondoskodunk, úgy azt zett riport természetesen ilyenkor sem statikus, valóban nem kell megváltoztatni, hiszen a genehiszen ennek talán semmi értelme sem lenne. Az rátor valójában nem is tudja, hogy az adatokat adatokat ekkor a riport paraméterek Map objekhonnan kapja, ő csak egy JRDataSource intertumán keresztül továbbítjuk a generátor részére. fésszel rendelkező objektummal kommunikál. 29 JasperReports 1 2 3 4

5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 A JasperReports adatforrások használata // 3−2. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; . public s t a t i c void testMapArray ( ) throws E x c e p t i o n { Map [ ] aMap = new HashMap [ 1 0 0 0 ] ; f o r ( i n t i = 0 ; i < 1 0 0 0 ; i ++) { Map map = new HashMap ( ) ; map . put ( "ORSZAG" , "ORSZAG−" + i ) ; map . put ( "FOVAROS" , "FOVAROS−" + i ) ; map .

put ( "FOLDR HELY" , "FOLDR HELY−" + i ) ; map . put ( "TERULET" , new BigDecimal ( ( i + 1 ) ∗ 1 0 0 0 ) ) ; aMap [ i ] = map ; } JRDataSource j r d s = new JRMapArrayDataSource (aMap) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r F i l e , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void t e s t M a p C o l l e c t i o n ( ) throws E x c e p t i o n { L i s t l i s t = new A r r a y L i s t ( ) ; f o r ( i n t i = 0 ; i < 1 0 0 0 ; i ++) { Map map = new HashMap ( ) ; map . put ( "ORSZAG" , "ORSZAG−" + i ) ; map . put ( "FOVAROS" , "FOVAROS−" + i ) ; map . put ( "FOLDR HELY" , "FOLDR HELY−" + i ) ; map . put ( "TERULET" , new BigDecimal ( ( i + 1 ) ∗ 1 0 0 0 ) ) ; } l i s t . add (map)

; JRDataSource j r d s = new JRMapCollectionDataSource ( l i s t ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; . // } 30 } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r F i l e , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testMapArray ( ) ; testMapCollection () ; } JasperReports A JasperReports adatforrások használata 3.1 ábra: Az országok riport - Map adatforrással A testMapArray() és testMapCollection() tesztmetódusok a tömb és List modellben megvalósított Map adatforrás használatot mutatják be, remélhetőleg ezek működését mindenki egyből érthetőnek találja. Nézzük a tömb esetét, a lista ezzel teljesen analóg! Felveszünk egy 1000 elemet befogadni képes aMap, tömböt, majd egy for ciklusban feltöltjük generált értékekkel. Arra

vigyázunk, hogy az egyes tömbelemek map objektumaiban használt kulcsnevek egyezzenek meg azzal, ami a jrxml mező nevek, hiszen ez a titka az egész működésnek. A jrds nevű JR2 MapArrayDataSource objektum az aMap objektummal lesz megkonstruálva. Ezután az eddigiek során is használt 1 db riport paraméterről is gondoskodunk, majd fillReportToFile() 4. paramétereként ezt a jrds adatforrást használjuk Az eredményt, azaz a létrejött riport egy részletét a 3.1 ábrán tekinthetjük meg A lista alapú példa is hasonlóan működik és természetesen pontosan ugyanezt a jrprint fájlt hozza létre. POJO=Plain Old Java Object 31 JasperReports A JasperReports adatforrások használata nem csak a riportban ténylegesen meghivatkozott mezőket hívja fel, hanem az összes deklaA következő és a Java eszköztárához közel ráltat, emiatt volt szükséges a használt 4 bean álló adatforrás típus a JavaBean (más néjellemzőn kívüliek megszüntetése. Az

alternaven: POJO 2 vagy Value Object) alapú megtíva az OrszagBean class kibővítése lett volna oldás. Itt is létezik egy névkonvenciós szab// 3−4 P r o g r a m l i s t a : OrszagBean j a v a vány, ami jó alapja lehet a jrxml field nevek és a bean property-k közötti összekapcsolásnak. package o r g c s t e s t ; Egy property neve legyen property, ekkor annak import j a v a . math BigDecimal ; publikus getter és setter metódusának a neve public c l a s s OrszagBean ebből úgy lesz képezve, hogy az set vagy get { private S t r i n g o r s z a g ; karaktersorozattal kezdődik, majd a property private S t r i n g f o v a r o s ; neve úgy, hogy az első karaktere nagybetű lesz. private S t r i n g f o l d r a j z i h e l y ; private BigDecimal t e r u l e t ; Példa: getProperty(). Ennek megfelelően csináltunk egy másolatot Orszagok-Beanjrxml (egy public S t r i n g g e t O r s z a g ( ) { részletét mutatja a 3-3. Programlista) néven, return o r s z a g ;

ahol csak a következő 3 változtatást eszközöltük: } A java objektum alapú adatforrás • A mezők nevét csupa kisbetűre alakítottuk • A textField komponensekben lévő $F{} hivatkozásokat is javítottuk, azaz például a $F{ORSZAG}$F{orszag} változtatást megtettük. • A fölösleges, a riportban és emiatt a beanből hiányzó field-ek törlése. < !−− 3−3. P r o g r a m l i s t a : Orszagok−Bean j r x m l −−> . < f i e l d name=" o r s z a g " c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name=" f o v a r o s " c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name=" f o l d r a j z i h e l y " c l a s s=" j a v a . l a n g S t r i n g å " /> < f i e l d name=" t e r u l e t " c l a s s=" j a v a . math B i g D e c i m a l " /> . public void s e t O r s z a g ( S t r i n g o r s z a g ) { this . orszag = orszag ;

} public S t r i n g g e t F o v a r o s ( ) { return f o v a r o s ; } public void s e t F o v a r o s ( S t r i n g f o v a r o s ) { this . fovaros = fovaros ; } public S t r i n g g e t F o l d r a j z i h e l y ( ) { return f o l d r a j z i h e l y ; } public void s e t F o l d r a j z i h e l y ( S t r i n g å Az OrszagBean class (3-4. Programlista) úgy foldrajzi hely ) készült, hogy ezeket a mezőket tartalmazza és il{ this . f o l d r a j z i h e l y = f o l d r a j z i h e l y ; leszkedjen ezekre a property nevekre. Itt említ} jük meg a riportgenerátorral kapcsolatos egyik public BigDecimal g e t T e r u l e t ( ) gyakorlati tapasztalatunkat, ami az a mechaniz{ return t e r u l e t ; mus, ahogy az aktuális sorból a generátor kiveszi } az értékeket. Az első kísérletnél a jrxml fájlpublic void s e t T e r u l e t ( BigDecimal t e r u l e t ) ban minden mezőt otthagytunk, ami egy prog{ ram exception-höz vezetett, ugyanis a következő this . t e r

u l e t = t e r u l e t ; } adatforrás sorra lépéskor a generátor előre fel } akarja tölteni a field-ek értékét, de a felvett 4 property kivételével a többit természetesen nem Végül nézzük meg a 3-5. Programlista segíttudta Ez azt is jelenti, hogy a JasperReports ségével a JavaBean adatforrás használatát! 32 JasperReports 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 A JasperReports adatforrások használata // 3−5. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j a s p e r " ; s t a t i c S t r i n g j a s p e r B e a n F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p

e l d a −1/Orszagok−Bean . j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; . public s t a t i c void t e s t B e a n A r r a y ( ) throws E x c e p t i o n { OrszagBean [ ] beans = new OrszagBean [ 1 0 0 0 ] ; f o r ( i n t i = 0 ; i < 1 0 0 0 ; i ++) { OrszagBean bean = new OrszagBean ( ) ; bean . s e t O r s z a g ( "BORSZAG−" + i ) ; bean . s e t F o v a r o s ( "BFOVAROS−" + i ) ; bean . s e t F o l d r a j z i h e l y ( "BFOLDR HELY−" + i ) ; bean . s e t T e r u l e t (new BigDecimal ( ( i + 1 ) ∗ 1 0 0 0 ) ) ; beans [ i ] = bean ; } JRDataSource j r d s = new JRBeanArrayDataSource ( beans ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r B e a n

F i l e , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void t e s t B e a n C o l l e c t i o n ( ) throws E x c e p t i o n { L i s t <OrszagBean> l i s t = new A r r a y L i s t <OrszagBean >() ; f o r ( i n t i = 0 ; i < 1 0 0 0 ; i ++) { OrszagBean bean = new OrszagBean ( ) ; bean . s e t O r s z a g ( "BLORSZAG−" + i ) ; bean . s e t F o v a r o s ( "BLFOVAROS−" + i ) ; bean . s e t F o l d r a j z i h e l y ( "BLFOLDR HELY−" + i ) ; bean . s e t T e r u l e t (new BigDecimal ( ( i + 1 ) ∗ 1 0 0 0 ) ) ; l i s t . add ( bean ) ; } JRDataSource j r d s = new J R B e a n C o l l e c t i o n D a t a S o u r c e ( l i s t ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r B e a n F i l e , j r p r i n t F i l e , params , j r d s ) ; . // } } public s

t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testBeanArray () ; testBeanCollection () ; } 33 JasperReports A 11-31 sorok közötti testBeanArray() a tömbbe szervezett JavaBean-ek esete. A 13 sorban egy 1000 elemű beans tömb kerül megadásra, aminek a szerepe megegyezik a Map-es példáéval, azaz az egyes tömbelemek az adatforrás „sorai”. A 15-23 sorok a tesztadatok generálását valósítják meg Témánk szempontjából a 25 sor szerepe fontos, ugyanis itt hozzuk létre a JRBeanArrayDataSource jrds objektumot, azaz a JavaBean alapú adatforrást. A jrds belül természetesen a beans tömbre épülve fog működni A 27-28 sorok a szokásos 1 db riport paramétert adják meg, a példa szempontjából lényegtelen a szerepe, akár törölhetnénk is. A 30 sor gyártja le a riportot, immár a beans adataira épülve. A fillReportToFile() 1 paramétere a jasper fájl, azaz a riport template. A 2 paramétere az eredményként létrejövő

jrprint fájl neve. A 3 a paraméterek Map-ja A 4 pedig a bean alapú adatforrásunk A 33-54 sorok közötti testBeanCollection() teszt metódus működése teljesen hasonló, de itt a tömb helyett egy lista tartalmazza az OrszagBean objektumokat, ennek megfelelően a 47. sor adatforrás objektuma is ilyen működésű implementációt példányosít Végezetül szeretnénk megjegyezni, hogy a JavaBean alapú adatforrás implementációja az Apache Commons Bean Utils megoldásra épül: http://commons.apacheorg/beanutils/, így annak jar könyvtára szükséges. XML adatforrás Az XML egy kiemelt jelentőséggel bíró adatformátum, mert több jó tulajdonsága is van: • könnyen hordozható a platformok között és önleíró • hierarchikus szerkezetével az adatok közötti belső szerkezetet is jól lehet ábrázolni Emiatt nagy előny, hogy a JasperReports támogatja azt a lehetőséget, hogy a jelentés adatforrása egy XML dokumentum is lehet, aminek 34 A JasperReports

adatforrások használata kezelési formátuma is tetszőleges: fájl, string, stream (byte folyam). Maradjunk az eddigi „országos” példánknál, így elkészítettünk egy új, orszagokxml fájlt (3-6 Programlista), amiben az /orszagok/item útvonal alatt a már ismerős adataink foglalnak helyet. // 3 −6. P r o g r a m l i s t a : o r s z a g o k xml <o r s z a g o k> <item> <o r s z a g>Magyar1</ o r s z a g> <f o v a r o s>Budapest</ f o v a r o s> <f o l d r a j z i h e l y>CE</ f o l d r a j z i h e l y> < t e r u l e t>93000</ t e r u l e t> </ item> <item> <o r s z a g>Orszag 2</ o r s z a g> <f o v a r o s>Fováros 2</ f o v a r o s> <f o l d r a j z i h e l y>CE</ f o l d r a j z i h e l y> < t e r u l e t>3213123</ t e r u l e t> </ item> <item> <o r s z a g>Orszag 3</ o r s z a g> <f o v a r o s>Fovaros 3</

f o v a r o s> <f o l d r a j z i h e l y>CE</ f o l d r a j z i h e l y> < t e r u l e t>9534500</ t e r u l e t> </ item> <item> <o r s z a g>Orszag 4</ o r s z a g> <f o v a r o s>Fovaros 4</ f o v a r o s> <f o l d r a j z i h e l y>CE</ f o l d r a j z i h e l y> < t e r u l e t>93000</ t e r u l e t> </ item> </ o r s z a g o k> Az Orszagok.jrxm template alapján elkészítettünk egy Orszagok-XMLjrxml (3-7 Programlista) változatot, ami a field mezők kivételével mindenben megegyezik az előzőekkel, így szemléltetésként csak azt a jrxml részletet tettük ide be. A fieldDescription most egy új elem, eddig erre nem volt szükség, amikor a field -eket megadtuk. XML esetén viszont kötelező, azt mondjuk meg vele, hogy például a fovaros mező az XML fovaros tag-jéből veszi ki az adatokat. Itt szeretnénk kiemelni, hogy a field neve és az XML tag neve eltérhet

egymástól, ezek egyezése nem követelmény, hiszen itt úgyis összerendelődnek. A <fovaros> tag neve lehetett volna akár <capital> is. Ez a mechanizmus rugalmasabbá teszi a különféle helyekről érkező XML adatforrások használatának lehetőségét. JasperReports 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 A JasperReports adatforrások használata // 3 −7. P r o g r a m l i s t a : Orszagok−XML j r x m l <j a s p e r R e p o r t . . <p a r a m e t e r name=" p h e a d e r T e r u l e t " c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name=" f o v a r o s " c l a s s=" j a v a . l a n g S t r i n g "> < f i e l d D e s c r i p t i o n>< ! [CDATA[ f o v a r o s ] ] ></ f i e l d D e s c r i p t i o n> </ f i e l d> < f i e l d name=" o r s z a g " c l a s s=" j a v a . l a n g S t r i n g "> < f i e l d D e s c r

i p t i o n>< ! [CDATA[ o r s z a g ] ] ></ f i e l d D e s c r i p t i o n> </ f i e l d> < f i e l d name=" f o l d r a j z i h e l y " c l a s s=" j a v a . l a n g S t r i n g "> < f i e l d D e s c r i p t i o n>< ! [CDATA[ f o l d r a j z i h e l y ] ] ></ f i e l d D e s c r i p t i o n> </ f i e l d> < f i e l d name=" t e r u l e t " c l a s s=" j a v a . math BigDecimal "> < f i e l d D e s c r i p t i o n>< ! [CDATA[ t e r u l e t ] ] ></ f i e l d D e s c r i p t i o n> </ f i e l d> <background> <band s p l i t T y p e=" S t r e t c h " /> </ background> . </ j a s p e r R e p o r t> Van jrxml template-ünk, le is fordítottuk, illetve rendelkezünk egy XML adatforrással. Még az van hátra, hogy megtanuljuk a JRXmlDataSource használatát, amit az eddigi gyakorlatot folytatva a TestOrszagokRiport class egy

módosított verziója (3-8. Programlista) segítségével fogunk bemutatni. Példánkban az is újdonság, hogy most kétféleképpen is megmutatjuk a használatot: alapján. A 37, illetve 47 sorokban lévő JRXmlDataSource objektum előállítása innen már vagy az InputStream, vagy a File objektumra épülve megy. Vegyük észre azonban, hogy a konstruktor mindkét esetben tartalmaz egy XPath hivatkozást az XML fa egy útjára: /orszagok/item Ez azt jelenti, hogy az XML-ben eljutva az item elem szintjéig, azon kell végiglépdelnie az adatforrásnak. A példa XML például 4 soros, mert • Az XML-t közvetlenül a fájlra hivatkozva most éppen 4 db item eleme van. A jrds adatforrás objektum legyártása után már az ismert szerezzük meg: testXMLFromFile() paraméterezés és riportkészítés történik. Ismét• Az XML egy InputStream objektumból ér- lésként a fillReportToFile() metódus paramétekezik: testXML() reinek jelentése: Nézzük a példát! A 30. sorban

egy új jasper • jasperFile: A jasper fájl, ami a jrxml fájl fájlra való hivatkozást látunk, ami a 3-7. Progfordításaként keletkezik (String típus) ramlistán mutatott kis jrxml változtatás miatt vált szükségessé. A testXML() 35 sorában a • jrprintFile: A jrprint fájl neve, ahova elJRLoader beépített class segítségével egy Inputkészül a riport (String típus). Stream formájában állítjuk elő az XML fájlunk tartalmát. Ez a byte-sorozat előállítás persze • params: A paraméterek objektuma (Map több más módon is történik a gyakorlatban, de típus). ha már itt az XML fájl, akkor miért ne abból vegyük ki. A testXMLFromFile() 46 sorában • jrds: A riport elkészítéséhez használt adatezzel szemben egy jól ismert java File objektuforrás (JRXmlDataSource típus). mot hozunk létre, persze szintén az orszagok.xml 35 JasperReports 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37

38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 A JasperReports adatforrások használata // 3−8. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; import import import import import import import import import import import import import import import import import import import import import import java . io F i l e ; j a v a . i o InputStream ; j a v a . math BigDecimal ; java . u t i l ArrayList ; j a v a . u t i l HashMap ; java . u t i l List ; java . u t i l Locale ; j a v a . u t i l Map ; n e t . s f j a s p e r r e p o r t s e n g i n e JRDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e JRException ; net . s f j a s p e r r e p o r t s engine JRResultSetDataSource ; net . s f j a s p e r r e p o r t s engine JasperFillManager ; net . s f j a s p e r r e p o r t s engine JasperReport ; n e t . s f j a s p e r r e p o r t s e n g i n e data

JRBeanArrayDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data J R B e a n C o l l e c t i o n D a t a S o u r c e ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRCsvDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRMapArrayDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRMapCollectionDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRXlsDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRXlsxDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e data JRXmlDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e u t i l JRLoader ; public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−XML. j a s p e r " ; . public s t a t i c void testXML ( ) throws E x c e p t i o n { InputStream i s = JRLoader . g e t L

o c a t i o n I n p u t S t r e a m ( " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/å o r s z a g o k . xml" ) ; JRDataSource j r d s = new JRXmlDataSource ( i s , " / o r s z a g o k / item " ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r F i l e , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void testXMLFromFile ( ) throws E x c e p t i o n { F i l e f i l e = new F i l e ( " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/ o r s z a g o k . xml" ) ; JRDataSource j r d s = new JRXmlDataSource ( f i l e , " / o r s z a g o k / item " ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; . // } 36 } J a s p e r F i l l M a n a g e r . f i l l R

e p o r t T o F i l e ( j a s p e r F i l e , j r p r i n t F i l e , params , j r d s ) ; // Only t e s t public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testXMLFromFile ( ) ; testXML ( ) } JasperReports Az elkészült riport kinézetét a 3.1 ábrán már láthattuk. Itt is megjegyezzük, hogy az XML adatforrások használatához a xalan jar fájlt (Java XPath kezelő könyvtár) szükséges használni, ami természetesen része a JasperReports csomagnak, de letölthető innen is: http: //xml.apacheorg/xalan-j/ A JasperReports adatforrások használata ban automatizálható vagy talán az excel tábla csak egy összetettebb adatforrás része. A 32 ábra az ismert példánkhoz illeszkedő adatok xls táblába való elhelyezését mutatja (orszagok.xls) Excel adatforrás Az excel formátum vitathatatlanul az egyik legelterjedtebb, táblázatos adattárolási forma. Bár a pivot tábla kiváló riportkészítő eszköz, azért elképzelhető,

hogy a feladatot valamilyen szempontból hatékonyabb, kifejezetten riportkészítő környezetben célszerű elvégezni. Esetleg így job1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 3.2 ábra: Excel adatok // 3−9. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . import j x l . Workbook ; import j x l . WorkbookSettings ; import j x l . w r i t e WritableWorkbook ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r B e a n F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−Bean . j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; . public s t a t i c void t e s t X l s ( ) throws E x c e p t i o n { S t r i n g f i l e N a m e = " /home/ t a n u l a s / j a s p

e r r e p o r t / p e l d a −1/ o r s z a g o k . x l s " ; S t r i n g [ ] columnNames = new S t r i n g [ ] { " orszag " , " fovaros " , " foldrajzi hely " , " t e r u l e t " }; i n t [ ] c o l u m n I n d e x e s = new i n t [ ] { 0, 1, 2, 3 }; // // // InputStream i s = JRLoader . g e t L o c a t i o n I n p u t S t r e a m ( f i l e N a m e ) ; JRDataSource j r d s = new JRXlsDataSource ( i s ) ; JRDataSource j r d s = new JRXlsDataSource ( new F i l e ( f i l e N a m e ) ) ; WorkbookSettings ws = new WorkbookSettings ( ) ; ws . s e t E n c o d i n g ( " Cp1252 " ) ; Workbook wb = Workbook . getWorkbook (new F i l e ( f i l e N a m e ) , ws ) ; JRDataSource j r d s = new JRXlsDataSource ( wb ) ; ( ( JRXlsDataSource ) j r d s ) . setColumnNames ( columnNames , c o l u m n I n d e x e s ) ; ( ( JRXlsDataSource ) j r d s ) . s e t L o c a l e (new L o c a l e ( "hu HU" ) ) ; 37 JasperReports 39 40 41 42 43 44

45 46 47 48 49 50 A JasperReports adatforrások használata HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; . } } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r B e a n F i l e , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testXls () ; } Az xls tábla, mint adatforrás használatát a 39. Programlista mutatja Készítsünk a 16 sorban megadott szerény, 4 soros táblánkhoz egy eddigiekhez tökéletesen hasonló jelentést. Ezt úgy biztosítjuk, hogy a 11. sorban is látottak szerint pont ugyanazt a riport template-et használjuk, amit a Java Bean-es példában is. A 1825 sorok között columnNames és columnIndexes tömböket azért hoztuk létre, hogy ami természetesen szintén része a JasperReports csomagnak, de külön is letölthető. A 35 sorban legyártjuk az excel

adatforrást, majd a 37-38 sorokban beállítjuk az oszlopneveket és a nyelvet. Itt a cast azért szükséges, mert ezek a metódusok már implementáció függőek és mint ilyet nem lehet a JRDataSource felületen elérni őket. A 43. sorban ismert módon elkészítjük a jrprint fájlt. 1. az egyes oszlopoknak nevet adjunk, hiszen a riport field-ek ezt igénylik, CSV adatforrás 2. megmondjuk, hogy az egyes nevek melyik Tekintsük a 3-10 Programlista által tartalmasorszámú (nullával kezdve) oszlophoz tar- zott csv fájlt! A most mutatott példa akkor toznak. is működik, ha az egyes értékeket idézőjel közé A 27-29 sorok szerint is tudnánk JRXlsData- tesszük, például „Budapest”. Source adatforrást készíteni, de a példában most1 // 3 −10. P r o g r a m l i s t a : o r s z a g o k c s v 31-33 sorok között létrejött Workbook objektu-23 Magyarország , Budapest , CE, 1 0 0 0 mot (a neve: wb) használjuk erre. Ez az osztály4 Ország 2 , Főváros 1 ,CE, 1

1 1 3 , B e r l i n , CE, 3 3 3 3 3 a JExcelAPI (webhelye: http://jexcelapi.56 Ország Ország 4 , Főváros 3 ,CE, 2 2 2 2 sourceforge.net/) jar könyvtárból származik, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 3 −11. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r B e a n F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−Bean . j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; public s t a t i c void t e s t C s v ( ) throws E x c e p t i o n { S t r i n g f i l e N a m e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/ o r s z a g o k . c s v " ; S t r i n g [ ] columnNames = new S t r i n g [ ] { " orszag " , " fovaros

" , " foldrajzi hely " , " t e r u l e t " 38 JasperReports 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 A JasperReports adatforrások használata }; i n t [ ] c o l u m n I n d e x e s = new i n t [ ] { 0, 1, 2, 3 }; // InputStream i s = JRLoader . g e t L o c a t i o n I n p u t S t r e a m ( f i l e N a m e ) ; JRDataSource j r d s = new JRCsvDataSource ( f i l e N a m e ) ; ( ( JRCsvDataSource ) j r d s ) . s e t R e c o r d D e l i m i t e r ( " " ) ; ( ( JRCsvDataSource ) j r d s ) . setColumnNames ( columnNames ) ; ( ( JRXlsDataSource ) j r d s ) . s e t L o c a l e ( new L o c a l e ("hu HU") ) ; // HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r B e a n F i l e , j r p r i n t F i l e , params , j r d s ) ; } public s t a t i c void

main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testCsv () ; } } A 3-11. Programlista programja az exceles testvéréhez hasonlóan működik Használhatnánk az is InputStream-et (23 sor) is, de most inkább a 24. sorban bemutatott módszerrel gyártottuk le a JRCsvDataSource adatforrást Esetünkben a sorok (a record) és oszlopok elhatárolóinak megadása is lényeges. A 25 sorban azt definiáltuk, hogy 2 sort a newline karakter választ el egymástól Az oszlopok elválasztó jelét a setFieldDelimiter() metódussal adhattuk volna meg, de most hagytuk, hogy az alapértelmezett vessző maradjon. A 33 sorban pedig elkészül a riportfájl. JSON adatforrás A JSON 3 az XML mellett manapság a másik elterjedt, hordozható adatformátum. Jelentősége akkor növekedett meg, amikor a WEB 2 rohamosan terjedni kezdett, hiszen leginkább a JavaScript biztosítja a böngészőben lévő működés dinamizmusát. A JasperReports a Jackson (webhelye:

http://jackson.codehausorg/) 3 JSON kezelő könyvtárat használja. A JSON egy JavaScript objektum szöveges leírással való megadása (Marshalling), amit • a JavaScript elő tud állítani és • belőle fel tudja építeni újra az objektumot. A Jackson ugyanerre képes, de az objektum ekkor egy Java osztálybeli példány. Itt egy izgalmas lehetőség mutatkozik a JavaScript↔Java kommunikációra, amint ezt az olvasó bizonyára tudja vagy sejti. Javasoljuk elolvasni a wiki JSON leírását: http://hu.wikipedia org/wiki/JSON. A Jackson használatával egy JSON szöveget könnyen át tudunk alakítani JavaBean, Map vagy XML formára, majd riportot készíthetünk vele, azonban a JasperReports ezt közvetlenül is el tudja végezni a JsonDataSource osztály használatával. Továbbfolytatva a hagyományt, most az országok adatait JSON formában is leírtuk, amit a 3-12. Programlista tartalmaz. Látható, hogy az Orszagok objektum Items mezője egy tömb, ami a mi ismerős

sorainkat (rekordjainkat) tartalmazza. JSON=JavaScript Object Notation 39 JasperReports A JasperReports adatforrások használata // 3 −12. P r o g r a m l i s t a : o r s z a g o k j s o n {" Orszagok " : { " Items " : [ { " o r s z a g " : " Magyarország " , " f o v a r o s " : " Budapest " , " f o l d r a j z i h e l y " : "CE" , " t e r u l e t " : "93000" }, { " o r s z a g " : " Orszag 2 " , " f o v a r o s " : " Budapest " , " f o l d r a j z i h e l y " : "CE" , " t e r u l e t " : "93000" }, { " o r s z a g " : " Orszag 3 " , " f o v a r o s " : " Budapest " , " f o l d r a j z i h e l y " : "CE" , " t e r u l e t " : "93000" }, { " o r s z a g " : " Orszag 4 " , " f o v a r o s

" : " Budapest " , " f o l d r a j z i h e l y " : "CE" , " t e r u l e t " : "93000" } ] }} 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 3.3 ábra: A JsonDataSource A 3-13. Programlista ennek a feldolgozását, azaz a jelentés elkészítését mutatja, aminek az eredményét a 3.3 ábrán láthatjuk // 3 −13. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . import n e t . s f j a s p e r r e p o r t s e n g i n e u t i l JRLoader ; import n e t . s f j a s p e r r e p o r t s e n g i n e data JsonDataSource ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g jasperXMLFile = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−XML. j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a

−1/Orszagok . j r p r i n t " ; public s t a t i c void testJSON ( ) throws E x c e p t i o n { InputStream i s = JRLoader . g e t L o c a t i o n I n p u t S t r e a m ( " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/å orszagok . json " ) ; JRDataSource j r d s = new JsonDataSource ( i s , " Orszagok . I t e m s " ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; } } 40 J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( jasperXMLFile , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testJSON ( ) ; } JasperReports A JSON jrxml-ben lévő field – az XML adatforráshoz hasonlóan – is igényli a fieldDescription leírást, emiatt ugyanazt a jasper lefordított fájlt használjuk a példában. A 15 sorban egy is InputStream-et készítünk az

orszagok.json tartalma alapján A 17 sorban gyártjuk le a jrds adatforrás objektumot, ahol a konstruktor 2. paraméterében szintén megadtuk azt az útvonalat, ahogy a mezőinkhez el lehet jutni Itt persze most az objektumoknál megszokott „.”-tal választottuk el a path elemeit: Orszagok.Items Erre úgy is gondolhatunk, mint egy select-re, hiszen annyi sort ad vissza, amennyi eleme van az Items tömbnek, az oszlopok pedig a rekord mezői. A 21 sorban a már többször látott riportkészítési lépés történik A JasperReports adatforrások használata ami a JRDataSource Java interface egy implementációjának megadását jelenti. Itt bármi olyan struktúra szóba jöhet, amit sorként és oszlopként lehet értelmezni. Azonban a lehetőségek még ennél is rugalmasabbak, mert ezeknek csak logikai kapcsolat szempontjából kell létezniük és csak arról kell gondoskodnunk, hogy a next() és getFieldValue() metódusok kiszámíthatóak legyenek. Például, ha létezik 1

adatbázis, ami az országok adatait tartalmazza, de nincs benne ez a 2 adat: • Az utolsó év GDP értéke (gdp) • A munkaképes lakosság száma (workers) A zárójelbe a képzeletbeli jrxml field neveket tettük. Találtunk az Interneten 2 webservice-t, mindkettőnek az ország ISO kódját lehet átadni Saját készítésű adatforrás és a kívánt gdp vagy workers értéket visszaadja. Mostanra sokféle adatforrást átnéztünk, talán Ekkor erre építve már készíthetnénk egy JROelég benyomást és tapasztalatot szereztünk ab- konomiaDataSource class-t, amivel a szükséges ban, hogy próbaként készítsünk egy sajátot is, riportot könnyedén elkészíthetnénk. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 // 3 −14. P r o g r a m l i s t a : JRMyExcelDatasource j a v a package o r g . c s t e s t ; import import import import import import import import import import import import import java . io F i l e ; j a v a . i

o IOException ; j a v a . math BigDecimal ; j a v a . math B i g I n t e g e r ; jxl . Cell ; j x l . CellType ; j x l . Sheet ; j x l . Workbook ; j x l . WorkbookSettings ; n e t . s f j a s p e r r e p o r t s e n g i n e JRDataSource ; n e t . s f j a s p e r r e p o r t s e n g i n e JRException ; n e t . s f j a s p e r r e p o r t s e n g i n e JRField ; n e t . s f j a s p e r r e p o r t s e n g i n e b a s e JRBaseField ; public c l a s s JRMyExcelDatasource implements JRDataSource { Workbook wb = n u l l ; Sheet s h e e t = null ; i n t actualRow = 0 ; public JRMyExcelDatasource ( S t r i n g f i l e N a m e , i n t sheetNumber ) throws E x c e p t i o n { actualRow = −1; WorkbookSettings ws = new WorkbookSettings ( ) ; ws . s e t E n c o d i n g ( " Cp1252 " ) ; wb = Workbook . getWorkbook (new F i l e ( f i l e N a m e ) , ws ) ; 41 JasperReports 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61

62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 } A JasperReports adatforrások használata s h e e t = wb . g e t S h e e t ( sheetNumber ) ; @Override public boolean n e x t ( ) throws JRException { boolean e x i s t N e x t = f a l s e ; actualRow++; C e l l c = null ; try { c = s h e e t . g e t C e l l ( actualRow , 0 ) ; } catch ( E x c e p t i o n e ) { existNext = false ; return e x i s t N e x t ; } CellType c t = c . getType ( ) ; i f ( c t . e q u a l s ( CellType EMPTY) ) { existNext = false ; wb . c l o s e ( ) ; } else { e x i s t N e x t = true ; } } return e x i s t N e x t ; @Override public O b j e c t g e t F i e l d V a l u e ( JRField j r f ) throws JRException { Object o = null ; S t r i n g numberStr = j r f . getName ( ) s u b s t r i n g ( 1 ) ; i n t c o l = I n t e g e r . p a r s e I n t ( numberStr ) ; C e l l c = s h e e t . g e t C e l l ( c o l , actualRow ) ; String s t r = c . getContents () ; } } // j a v a .

math BigDecimal i f ( j r f . getValueClassName ( ) e q u a l s ( BigDecimal c l a s s getName ( ) ) ) { BigDecimal bd = new BigDecimal ( s t r ) ; o = bd ; } else { o = str ; } return o ; A 3-14. Programlista célja csak az adatforrás implementáció megtanítása, ezért egy Excel adatforrás (JRMyExcelDatasource) megvalósítását mutatja be, ugyanazzal a java library-vel, 42 amit a beépített adatforrás is használ. A 2532 sorok közötti konstruktor az xls fájl nevét és a használni kívánt excel munkalap sorszámát kapja meg, ami alapján létrehoz egy Workbook JasperReports (neve: wb) és egy Sheet (sheet) példányt. A 35. sornál kezdődő next() pont úgy működik, ahogy elvárjuk tőle: a tábla következő sorára áll, amíg azok el nem fogynak. Most nézzük az értékek előállítását biztosító getFieldValue() metódust! Itt említenénk meg egy tervezési döntést: a jrxm-ben az egyes mezők szerkezete ilyen lehet, amikor az egyes oszlopokra

hivatkozunk: <betű><oszlop sorszám>. Ez azt jelenti, hogy például a egy $F{O2} hivatkozás esetén, a JRField paraméter – más információk kíséretében – ezt a nevet fogja leszállítani a metódus számára. A 68-70 sorokban ez már elég lesz annak az adatnak a megszerzéséhez, hogy melyik sorszámú oszlop értéke kell, ezt a col változóba mentjük. Ezután a 72-73 sorban már Stringként tudjuk is a keresett értéket A JRField az érték típusát is átadja, így például BigDecimal esetén még erre át kell konvertálnunk a Stringet. Szeretnénk kiemelni, hogy ez az adatforrás implementáció nem produktív céllal készült, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 A JasperReports adatforrások használata annak nem minden ága van rendesen lekezelve, ugyanakkor a lehetséges érték típusok közül csak String és BigDecimal visszaadására képes, ami hiányos, hiszen a JRField a típus információt is átadja. A

field pedig számít arra, hogy megfelelő típusú Object jött neki vissza Persze, ha vigyázunk, hogy csak ezen 2 típust használjuk a jrxml-ben, akkor már egészen jól működik az adatforrás. Ezt látjuk a 3-15 Programlistán, ezeket a mezőket használtuk tesztelés során. // 3 −15. P r o g r a m l i s t a : Orszagok−XLS j r x m l <j a s p e r R e p o r t . . < f i e l d name="C0" c l a s s=" j a v a . l a n g å S t r i n g " /> < f i e l d name="C1" c l a s s=" j a v a . l a n g å S t r i n g " /> < f i e l d name="C2" c l a s s=" j a v a . l a n g å S t r i n g " /> < f i e l d name="C3" c l a s s=" j a v a . math å BigDecimal " /> <background> . </ j a s p e r R e p o r t> // 3 −16. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s

p e r M y F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−MyXls . j a s p e r " ; s t a t i c S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; public s t a t i c void testMyJRDS ( ) throws E x c e p t i o n { S t r i n g f i l e N a m e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/ o r s z a g o k . x l s " ; JRDataSource j r d s = new JRMyExcelDatasource ( f i l e N a m e , 0 ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; J a s p e r R e p o r t j r = ( J a s p e r R e p o r t ) JRLoader . l o a d O b j e c t (new F i l e ( j a s p e r M y F i l e ) ) ; // } } J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r M y F i l e , j r p r i n t F i l e , params , j r d s ) ; J a s p e r F i l l M a n a g e

r . f i l l R e p o r t T o F i l e ( j r , j r p r i n t F i l e , params , j r d s ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testMyJRDS ( ) ; } A 3-16. Programlista a saját készítésű adatforrásunk használatát mutatja be, abban semmi újdonság nem található 43 JasperReports 4. Hordozható dokumentum formátumok készítése Hordozható dokumentum formátumok készítése Az eddigiek során mindig a JasperReports jrprint natív dokumentum formátumot állítottuk elő. Ezzel nincsen semmi baj, kivéve azt, hogy használatához a jasper környezet szükséges. A végterméknek nyilvánvalóan egy ismert dokumentum formátumnak kell lennie, amiket minden operációs rendszer alatt kezelni tudunk. Ebben a cikkben áttekintjük a szabványos, hordozható formátum előállításának lehetőségeit. Rövid ismétlő áttekintés Mostanra sok mindent megtanultunk, a továbblépés előtt érdemes egy kis összegző

áttekintést készíteni. A riportok kinézeti tervét a jrxml fájl tartalmazza, aminek a memóriában felépített JasperDesign class felel meg. Az 1-3 Programlista még azt is megmutatta, hogy a jrxmlből hogyan tudjuk ennek és a beállításainak a forráskódját előállítani. A JasperReport osztály a lefordított jrxml (azaz JasperDesign) objektumok osztálya, amiket a fájlrendszerbe jasper fájlokba tudunk perzisztálni. Az elkészült riportot a JasperPrint class reprezentálja, amit jrprint 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 fájlba tudunk menteni. Az 1-4 Programlista compile() metódusa megmutatta, hogy egy jrxml fájl jasper fájl fordítást milyen módon lehet programozottan elvégezni. A 4-1 Programlista tartalmaz egy új compileToJasperReport() nevű metódust, ahol JasperCompileManager class-tól azt kérjük, hogy jasper fájl helyett egy JasperReport objektumot adjon vissza. Megjegyezzük, hogy a JRXmlLoader osztály load() metódusa túlterhelt, a

megjegyzésbe tett rész egy alternatíva, ha nem InputStream-ből, hanem közvetlenül a jrxml fájlból akarjuk a jasperDesign objektumot elkészíteni. // 4−1. P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; . public c l a s s JRHelper { . public J a s p e r R e p o r t c o m p i l e T o J a s p e r R e p o r t ( S t r i n g jrxmlFileName ) throws E x c e p t i o n { JasperReport j r = null ; InputStream i s = new F i l e I n p u t S t r e a m ( new F i l e ( jrxmlFileName ) ) ; // J a s p e r D e s i g n j a s p e r D e s i g n = JRXmlLoader . l o a d ( jrxmlFileName ) ; J a s p e r D e s i g n j a s p e r D e s i g n = JRXmlLoader . l o a d ( i s ) ; J a s p e r R e p o r t j a s p e r R e p o r t = JasperCompileManager . c o m p i l e R e p o r t ( j a s p e r D e s i g n ) ; . } } return j r ; Az „üres” adatforrások pontnál már említet- fájlunk, úgy azt a 4-2. Programlistán látott gettük a JasperFillManager azon képességeit, hogy

JasperPrint() metódussal lehet JasperPrint oszmilyen formátumokba képes a riportot elkészí- tálybeli objektumba betölteni teni. Amennyiben már van elkészített jrprint 44 JasperReports 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 Hordozható dokumentum formátumok készítése // 4−2. P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; . public c l a s s JRHelper { . public J a s p e r P r i n t g e t J a s p e r P r i n t ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { F i l e f i l e = new F i l e ( j r p r i n t F i l e N a m e ) ; J a s p e r P r i n t j p = ( J a s p e r P r i n t ) JRLoader . l o a d O b j e c t ( f i l e ) ; . } } return j p ; A 4-3. Programlista makeReportToJasper- Print objektum legyártására képes Eddig minPrint() metódusa a jasper fájl, paraméter map dig a jrprint fájl készítést alkalmaztuk és egy adatforrás alapján közvetlenül a Jasper1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 // 4−3.

P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; . public c l a s s JRHelper { . public J a s p e r P r i n t makeReportToJasperPrint ( S t r i n g j a s p e r F i l e N a m e , HashMap params , å JRDataSource j r D s ) throws JRException { J a s p e r P r i n t j r p = null ; j r p = J a s p e r F i l l M a n a g e r . f i l l R e p o r t ( j a s p e r F i l e N a m e , params , j r D s ) ; . } } return j r p ; Most nem lesz rá szükség, de a teljesség érdekében a 4-4. Programlista makeReportToOutputStream() metódusa azt is bemutatja, hogy a reportot miként tudnánk OutputStream objektumként is elkészíteni. A 3-16 Programlista 16 1 2 3 4 5 6 7 8 9 10 sora azt tanította meg, hogy egy már lefordított és elmentett jasper fájlból hogyan lehet a memóriába visszaállítani a JasperReport objektumot. Ezt a technikát most itt is alkalmaztuk. // 4−4. P r o g r a m l i s t a : JRHelper j a v a package o r g . c s t e s t ; . public c l a s

s JRHelper { . public OutputStream makeReportToOutputStream ( S t r i n g j a s p e r F i l e N a m e , HashMap params , å JRDataSource j r D s ) throws E x c e p t i o n { OutputStream o s = n u l l ; 45 JasperReports 11 12 13 14 15 16 17 18 19 20 // Hordozható dokumentum formátumok készítése JasperReport j r = compileToJasperReport ( jasperFileName ) ; J a s p e r R e p o r t j r = ( J a s p e r R e p o r t ) JRLoader . l o a d O b j e c t (new F i l e ( j a s p e r F i l e N a m e ) ) ; J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o S t r e a m ( j r , os , params , j r D s ) ; . } } return o s ; Ennyi előkészítés után vágjunk bele a külön- mindig egy JRExporter interface-t biztosító obféle dokumentum formátumokba való exportálás jektummal tesszük meg, aminek a forráskódját lehetőségeinek megismerésébe! a 4-5. Programlista mutatja Az exportReport() metódus végzi el magát az exportálást, a többi csak annak működését

befolyásolja. A setParaA JRExporter interface meter() segítségével tetszőleges működési paraAmikor egy JasperPrint (vagy jrprint) hor- métereket adhatunk át, amire példákat majd a dozható dokumentum exportálást végzünk, ezt konkrét exportereknél fogunk látni. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 // 4−5. P r o g r a m l i s t a : JRExporter j a v a package n e t . s f j a s p e r r e p o r t s e n g i n e ; import j a v a . u t i l Map ; public i n t e r f a c e JRExporter { /∗ ∗ ∗ S e t s an e x p o r t parameter f o r advanced c u s t o m i z a t i o n o f t h e e x p o r t p r o c e s s . Parameterså can be e i t h e r ∗ common p a r a m e t e r s or s p e c i a l i z e d ones , d e p e n d i n g on t h e e x p o r t e r t y p e . ∗ @param parameter t h e parameter , s e l e c t e d from t h e s t a t i c p a r a m e t e r s d e f i n e d by å JasperReports ∗ @param v a l u e t

h e parameter v a l u e ∗ @see JRExporterParameter ∗/ public void s e t P a r a m e t e r ( JRExporterParameter parameter , O b j e c t v a l u e ) ; /∗ ∗ ∗ Gets an e x p o r t parameter . ∗/ public O b j e c t g e t P a r a m e t e r ( JRExporterParameter p a r a m e t e r ) ; /∗ ∗ ∗ S e t s e x p o r t p a r a m e t e r s from a s p e c i f i e d map . ∗ @see JRExporter#s e t P a r a m e t e r ( JRExporterParameter , O b j e c t ) ∗/ public void s e t P a r a m e t e r s (Map p a r a m e t e r s ) ; /∗ ∗ ∗ Gets a map c o n t a i n i n g a l l e x p o r t p a r a m e t e r s . ∗/ public Map g e t P a r a m e t e r s ( ) ; /∗ ∗ 46 JasperReports 38 39 40 41 42 Hordozható dokumentum formátumok készítése ∗ Actually s t a r t s the export process . ∗/ public void e x p o r t R e p o r t ( ) throws JRException ; } PDF dokumentumok Első feladatunk legyen a PDF exporter megismerése, hiszen talán ez a formátum a leggyakoribb. Példáinkat

a JRExportingHelper class tartalmazza, így nézzük meg a 4-6. Programlistát! A 17-28 sorok közötti pdfExport() metódus egy jrprint pdf exportálást képes elvégezni. A példaként szereplő jrprint fájl a 2. cikk adatbázisos példájából származik A 20 sorban a JRHelper class korábban ismertetett metódusával az Orszagok.jrprint fájl tartalmát visszaadjuk egy JasperPrint objektumként (a neve: jp) A 22. sorban létrehozzuk az exporter objektumot, amit a rákövetkező 3 sorban rendre ezekkel a paraméterekkel látjuk el: • A jp JasperPrint objektum • A legyártandó PDF fájl neve • A karakterkódolás 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 4.1 ábra: Exportált PDF dokumentum Végül a 27. sorban meghívjuk az exportReport() metódust, ami létrehozza a riport PDF formátumát. A 30-36 sorok között a most elkészített metódust le is teszteljük, aminek az eredményét a 41 ábrán láthatjuk // 4−6. P r o g r a m l i s t a : J R E x

p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import import . import java . io net . s f net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; . e n g i n e u t i l JRLoader ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t JRPdfExporter ; public c l a s s J R E x p o r t i n g H e l p e r { public void pdfExport ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JRHelper j h = new JRHelper ( ) ; JasperPrint jp = jh . getJasperPrint ( jrprintFileName ) ; JRExporter e x p o r t e r = new JRPdfExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; 47 JasperReports 24 25 26 27 28 29 30 31 32 33 34

35 36 37 Hordozható dokumentum formátumok készítése e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" p d f " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8" ) ; } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; } } J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; j r e h . pdfExport ( j r p r i n t F i l e ) ; természetesen hasonló a PDF-éhez, bár ahogy láthatjuk, most több vezérlő paramétert is megA textExport() metódust és annak a használaadtunk. tát a 4-7. Programlista foglalja magába Az elv Egyszerű text dokumentumok 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26

27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 // 4−7. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import import . import import java . io net . s f net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; . e n g i n e u t i l JRLoader ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t JRTextExporter ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t JRTextExporterParameter ; public c l a s s J R E x p o r t i n g H e l p e r { public void t e x t E x p o r t ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ; JRTextExporter e x p o r t e r =

new JRTextExporter ( ) ; // } e x p o r t e r . s e t P a r a m e t e r ( JRTextExporterParameter BETWEEN PAGES TEXT , " f " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRTextExporterParameter PAGE HEIGHT , new F l o a t ( 7 9 8 ) ) ; e x p o r t e r . s e t P a r a m e t e r ( JRTextExporterParameter PAGE WIDTH , new F l o a t ( 5 8 1 ) ) ; e x p o r t e r . s e t P a r a m e t e r ( JRTextExporterParameter CHARACTER WIDTH , new F l o a t ( 7 ) ) ; e x p o r t e r . s e t P a r a m e t e r ( JRTextExporterParameter CHARACTER HEIGHT , new F l o a t ( 1 4 ) ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" t x t " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s )

throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; } 48 } J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; jreh . textExport ( j r p r i n t F i l e ) ; JasperReports Hordozható dokumentum formátumok készítése Az eredmény egy részletét a Orszagok.jrprinttxt nevű szöveg mutatja 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 Orszagok . j r p r i n t t x t Az o r s z á g o k l e g f o n t o s a b b a d a t a i Titkos ! . Ország Főváros Földrész PORTUGÁLIA LISSZABON Dél−Európa : I b é r i a i −f é l s z i g e t 92082.00 SVÁJC BERN Közép−Európa :A lpok 41293.00 AUSZTRIA BÉCS Közép−Európa :A lpok 83858.00 MAGYARORSZÁG BUDAPEST Közép−Európa :K á r p á t −medence 93036.00 SZERBIA

BELGRÁD Dél−Európa : Bal kán− f é l s z i g e t 88361.00 SZLOVÁKIA POZSONY Közép−Európa :K árpátok 49036.00 MOLDOVA CHISINAU K e l e t −Európa 33700.00 TAJVAN TAJPEJ Á z s i a : Távol−Ke let 36000.00 6 / Area (km2) 7 . MS Word dokumentumok Az MS Word dokumentum előállítását a 4-8. Programlista kódja valósítja meg 1 2 3 4 5 6 7 8 9 10 // 4−8. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import java . io net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; 49 JasperReports 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 Hordozható dokumentum formátumok készítése import n

e t . s f j a s p e r r e p o r t s e n g i n e u t i l JRLoader ; . import n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t ooxml JRDocxExporter ; public c l a s s J R E x p o r t i n g H e l p e r { public void docExport ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ; JRExporter e x p o r t e r = new JRDocxExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" doc " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; // } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t "

; } } J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; j r e h . docExport ( j r p r i n t F i l e ) ; MS Excel dokumentumok Az MS Word dokumentum előállítását a 4-9. Programlista kódja valósítja meg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 // 4−9. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import import . import java . io net . s f net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; . e n g i n e u t i l JRLoader ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t JRXlsExporter ; public c l a s s J R E x p o r t i n g H e l p

e r { public void x l s E x p o r t ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ; JRExporter e x p o r t e r = new JRXlsExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" x l s " ) ; // e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; 50 JasperReports 33 34 35 36 37 } } Hordozható dokumentum formátumok készítése J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; jreh . xlsExport ( j r p

r i n t F i l e ) ; HTML dokumentumok HTML exporter használata is hasonló, a htmlExport() metódust és annak tesztjét a 4-10. Programlista tartalmazza, aminek eredményét a 42 ábrán meg is mutattuk 4.2 ábra: Exportált HTML dokumentum 1 2 3 4 5 6 7 8 9 // 4 −10. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import java . io net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; 51 JasperReports 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 Hordozható dokumentum formátumok készítése import n e t . s f j a s p e r r e p o r t s e n g i n e J a s p e r P r i n t ; import n e t . s f j a s p e r r e p o r t s e n g i n e u t i l JRLoader ; . import n e t . s

f j a s p e r r e p o r t s e n g i n e e x p o r t JRHtmlExporter ; public c l a s s J R E x p o r t i n g H e l p e r { public void htmlExport ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ; JRExporter e x p o r t e r = new JRHtmlExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" html " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; // } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; } } J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( )

; j r e h . htmlExport ( j r p r i n t F i l e ) ; OpenDocument táblázat Az OpenDocument táblázat dokumentum előállítását a 4-11. Programlista kódja valósítja meg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 // 4 −11. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import import . import java . io net . s f net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; . e n g i n e u t i l JRLoader ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t o a s i s JROdsExporter ; public c l a s s J R E x p o r t i n g H e l p e r { public void odsExport ( S t r i n g j r p r i n t F i l e N

a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ; JRExporter e x p o r t e r = new JROdsExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" ods " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; // } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; 52 JasperReports 32 33 34 35 36 } } Hordozható dokumentum formátumok készítése J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; j r e h . odsExport ( j r p r i n t F i l e ) ; OpenDocument szöveg Az OpenDocument szöveges

dokumentum előállítását a 4-12. Programlista kódja valósítja meg 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 // 4 −12. P r o g r a m l i s t a : J R E x p o r t i n g H e l p e r j a v a package o r g . c s t e s t ; import import import import import import import . import java . io net . s f net . s f net . s f net . s f net . s f net . s f . File ; jasperreports jasperreports jasperreports jasperreports jasperreports jasperreports . e n g i n e JRException ; . e n g i n e JRExporter ; . e n g i n e JRExporterParameter ; . e n g i n e JasperExportManager ; . engine JasperPrint ; . e n g i n e u t i l JRLoader ; n e t . s f j a s p e r r e p o r t s e n g i n e e x p o r t o a s i s JROdtExporter ; public c l a s s J R E x p o r t i n g H e l p e r { public void odtExport ( S t r i n g j r p r i n t F i l e N a m e ) throws JRException { JasperPrint jp = getJasperPrint ( jrprintFileName ) ;

JRExporter e x p o r t e r = new JROdtExporter ( ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter JASPER PRINT, j p ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter OUTPUT FILE NAME, j r p r i n t F i l e N a m e+" odt " ) ; e x p o r t e r . s e t P a r a m e t e r ( JRExporterParameter CHARACTER ENCODING, "UTF8") ; // } exporter . exportReport ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws JRException { S t r i n g j r p r i n t F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok . j r p r i n t " ; } } J R E x p o r t i n g H e l p e r j r e h = new J R E x p o r t i n g H e l p e r ( ) ; j r e h . odtExport ( j r p r i n t F i l e ) ; ben statikus metódusok biztosítják az ismert formátumú dokumentumok előállítását. Például a A fenti dokumentum exportálási lehetőségekhez PDF előállítást így is kérhettük volna: . e x p o r t R e p

o r t T o P d f F i l e ( jp , å a JasperReports csomag tartalmaz egy homlok- JasperExportManager j r p r i n t F i l e N a m e+" . p d f " ) ; zat osztályt, ez a JasperExportManager. Eb- A JasperExportManager class 53 JasperReports 5. Többnyelvű riportok készítése Többnyelvű riportok készítése Sok esetben elengedhetetlen, hogy jelentéseink többnyelvűek legyenek. Az alkalmazásoknál már megszoktuk, hogy egyetlen kattintással váltunk a nyelvek között, ami azt is jelenti, hogy ezt riportjainknak is követniük kell. Nézzük meg ennek a megvalósítását JasperReports-ban! A Java nyelv már a kezdeteknél támogatja a többnyelvűséget, ami alapvetően 3 komponensből áll: • A ResourceBundle class és a szövegeket leíró property fájlok, ahol kulcs/érték párokat használunk. • A Locale class, ami egy ország és nyelv együttesének értékét tárolja. • A különféle szöveges formátumok kultúrafüggő megjelentése (számok,

pénznem, dátum). Nyelvfüggő szövegek // orszagokText hu . p r o p e r t i e s t i t l e =Az o r s z u00e1gok l e g f o n t o s a b b a d a t a i d e n i e d=T i l o s c o u n t r y=Orsz u00e1g c a p i t a l=F u0151v u 0 0 e 1 r o s r e g i o n=F u 0 0 f 6 l d r a j z i h e l y a r e a=Ter u 0 0 f c l e t (km2) // orszagokText en . p r o p e r t i e s t i t l e =The most i m p o r t a n t data o f c o u n t r i e s d e n i e d=Top S e c r e t c o u n t r y=Country c a p i t a l=C a p i t a l r e g i o n=Region a r e a=Area (km2) // orszagokText de . p r o p e r t i e s t i t l e =I n den m e i s t e n L u00e4ndern , Daten d e n i e d=N i c h t c o u n t r y=Land c a p i t a l=Hauptstadt r e g i o n=Region a r e a=B e r e i c h (km2) Az országok riportnak most elkészítjük a nyelvfüggő változatát, ez most annyit fog jelenteni, hogy az adott nyelvnek megfelelő szövegek jelennek majd meg a keletkezett dokumentumban. Három nyelvre készítjük fel a riportunkat:

német, angol és magyar. Ennek megfelelően az egyes szövegelemeket egy-egy szöveges fájlban tároljuk el, amik rendre ezeket a fájl neveket kapják most: • orszagokText de.properties • orszagokText de.properties • orszagokText hu.properties Figyeljük meg, hogy az egyes nevek csak a hu, de és en betűkben különböznek egymástól, az „ ” jel után az ország 2 karakteres ISO kódja következik. Az egyes fájlok tartalma pedig az alábbi: 54 5.1 ábra: Többnyelvű riport terv (I18N) JasperReports Többnyelvű riportok készítése Az 5.1 ábra az iReport-ban áttervezett ri- pest eltérés csak a fájl első részében van, amely portot mutatja, ami nagyrészt megegyezik az részletet teljes egészében tartalmazza az 5-1. Orszagok.jrxml template-tel, az eddigiekhez ké- Programlista (Orszagok-I18Njrxml ) 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54

55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 5 −1. P r o g r a m l i s t a : Orszagok−I18N j r x m l <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−I18N " l a n g u a g e=" g r o o v y " pageWidth=" 595 " å p a g e H e i g h t=" 842 " columnWidth=" 555 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 "

bottomMargin=" 20 " å r e s o u r c e B u n d l e=" o r s z a g o k T e x t " u u i d=" 9 a1dbe76 −1ae5 −4418−9 e43−e 5 6 f 6 e d 9 8 1 9 3 "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y " v a l u e=" 0 " /> <p a r a m e t e r name=" p h e a d e r T e r u l e t " c l a s s=" j a v a . l a n g S t r i n g " /> <q u e r y S t r i n g l a n g u a g e="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s

s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math B i g D e c i m a l " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d

name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> <b a c k g r o u n d> <band s p l i t T y p e=" S t r e t c h " /> </ b a c k g r o u n d> < t i t l e> <band h e i g h t=" 79 " s p l i t T y p e=" S t r e t c h "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 69 af5ddd −3722−48b7 −8620 −5680547195 e a " x=" 68 " y=" 24 " w i d t h="å 411 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t s i z e=" 16 " i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F

i e l d E x p r e s s i o n>< ! [CDATA[ $R{ t i t l e } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ t i t l e > <p a g e H e a d e r> <band h e i g h t=" 35 " s p l i t T y p e=" S t r e t c h "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" e 3 3 0 b 4 e 8 −99b2 −4281−8260−3 c 4 7 3 d 3 6 6 4 9 2 " x=" 455 " y=" 0 " w i d t h="å 100 " h e i g h t=" 20 " f o r e c o l o r="#FF0000 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ d e n i e d } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ p a g e H e a d e r> <columnHeader> <band h e i g h t=" 42 " s p l i t T y p e=" S t r e t c

h "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 7 7 0 1 0 e10 −4c f a −4847−9047− e 9 6 6 e e 1 6 b a e c " x=" 24 " y=" 0 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ c o u n t r y } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" e 6 8 f c c 3 a −b 8 f 5 −411e −959c −83 c 8 4 5 9 0 6 0 b f " x=" 142 " y=" 0 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ c a p i t a l } ] ] ></ t e

x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 33381688 − a5c5 −4256−a309 −3576 b7bed762 " x=" 261 " y=" 0 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t> 55 JasperReports 72 73 74 75 76 77 78 79 80 81 82 83 84 85 </ band> </ columnHeader> . Többnyelvű riportok készítése <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ r e g i o n } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 7 cbb7ca1 −8dca −4eb5 −8bbc−c 2 0 d 9 0 1 3 f 4 d 2 " x=" 379 " y=" 0 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i

g n m e n t=" R i g h t "> <f o n t i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ a r e a } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> Az első fontos különbség a jasperReport tagben megadott resourceBundle="orszagokText" attribútum. Ez arra utasít, hogy a nyelvfüggő szövegelemeket az ilyen perfixű property fájlokból vegye ki, aminek egyébként a CLASSPATH on kell lennie. A másik változtatás a title, pageHeader és columnHeader címkéknél található textElement-eknél van (a staticText-eket visszamozgattuk). Vegyük azt is észre, hogy a textFieldExpression tag $R{} hivatkozásokat tar1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 talmaz, ahol az R a resource bundle-ra való utalás. Például a $R{capital} azt jelenti, hogy az a szöveg kell most ide, ami a

megfelelő property fájl capital kulcsához van írva. Az éppen aktuálisan használt Locale objektum választja majd ki, hogy a most lehetséges 3 nyelvfüggő fájl melyikéből emeljük ki. Az 5-2 Programlista pont azt mutatja be, hogy mindezt hogyan szabályozzuk, így nézzük meg! // 5−2. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r I 1 8 N F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−I18N . j a s p e r " ; public s t a t i c void testI18NRDBMS ( ) throws E x c e p t i o n { S t r i n g s q l = " s e l e c t ␣ ∗ ␣ from ␣ o r s z a g o k ␣ where ␣ t e r u l e t ␣<␣ ? " ; C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , å "" )

; P r e p a r e d S t a t e m e n t stmt = conn . p r e p a r e S t a t e m e n t ( s q l ) ; stmt . s e t D o u b l e ( 1 , 1 0 0 0 0 0 0 0 ) ; R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ) ; JRDataSource j r d s = new J R R e s u l t S e t D a t a S o u r c e ( r s ) ; JRHelper j h = new JRHelper ( ) ; HashMap params = new HashMap ( ) ; params . put ( " p h e a d e r T e r u l e t " , " Area ␣ (km2) " ) ; params . put ( JRParameter REPORT LOCALE, L o c a l e ENGLISH) ; j h . makeReport ( j a s p e r I 1 8 N F i l e , params , j r d s ) ; } } 56 rs . close () ; stmt . c l o s e ( ) ; conn . c l o s e ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testI18NRDBMS ( ) ; } JasperReports Többnyelvű riportok készítése hogy most éppen melyik lokalitás nyelvén szeretnénk a riportot elkészíteni. Ehhez a JRParameterREPORT LOCALE riport paramétert állítjuk Locale.ENGLISH értékre, azaz

jelentésünk angol lesz A 23 sorban elkészült riportot láthatjuk az 5.2 ábrán Lokális adatformátumok A ResourceBundle class 5.2 ábra: Többnyelvű riport (I18N) A 7. sor az a jasper fájl, amit frissen fordítottunk a megváltoztatott új jrxml miatt A riportunk most ismét a HSQLDB adatbázisból fogja venni az adatokat az ismert 11. sorban megadott SQL select szerint. Ezután a program egészen a 20 sorig ismerős dolgokat tartalmaz A 22 sor az, ahol átadjuk a riportnak, 1 2 3 4 5 6 7 8 Már említettük, hogy a Java osztálykönyvtár része a ResourceBundle class. Valójában az előző pontban megismert $R{.} hivatkozás is ezt alkalmazza a háttérben Használatát az 5-3 Programlistán mutatott kódrészlet mutatja be A jól ismert Locale class azt az információt tárolja, hogy melyik ország, melyik nyelvére gondolunk. Most a német értéket tettük a locale változóba. A 4. sorban a myResources nevű változó hivatkozást kap egy olyan ResourceBundle

objektumra, ami a már ismert orszagokText prefixű properties fájlokban tárolja a szöveg elemeket és a német változaton (2. paraméter) dolgozik A következő sorokban a használatát és annak képernyőn megjelenő eredményét láthatjuk. // 5 −3. P r o g r a m l i s t a : ResourceBundle L o c a l e l o c a l e = L o c a l e .GERMANY; ResourceBundle myResources = ResourceBundle . getBundle ( " o r s z a g o k T e x t " , l o c a l e ) ; System . out p r i n t l n ( myResources g e t S t r i n g ( " c a p i t a l " ) ) ; F u t á s i eredmény: Hauptstadt záférhetünk, így az értékét paraméterként átadhatjuk a riport számára, aminek a neve a pélElső lépésként a szövegrészleteket tartalmazó dánkban patternOfDate lesz majd. orszagokText xxx.properties fájlokat kiegészí- Német: dateFormat=MM/dd/ yyyy tettük a megfelelő területre jellemző dateForAngol: mat kulccsal, ami a nyelvfüggő dátumformátum dateFormat=dd /MM/ yyyy

maszk (yyyy=év, MM=hónap, dd=nap). Az 5- Magyar: dateFormat=yyyy /MM/ dd 3. Programlistán mutatott módon ehhez hozA nyelvfüggő dátumformátum 57 JasperReports Előtte azonban tekintsük át a OrszagokI18N.jrxml terven tett változtatásokat, hiszen most ki kell tennünk egy dátumot tartalmazó textField komponenst, aminek textFieldExpression részéhez definiálnunk kell a patternOfDate paramétert is. Az 5-4 Programlistán csak a változtatásokat láthatjuk A 6 sorban találjuk az 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 5 −4. P r o g r a m l i s t a : Orszagok−I18N j r x m l <q u e r y S t r i n g l a n g u a g e="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> . 25 26 . < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < t i t l e> <band h e i g h t=" 93 " s p l i t T y p e=" S t r e t c h "> < t e x t F i e

l d> <r e p o r t E l e m e n t u u i d=" 69 af5ddd −3722−48b7 −8620 −5680547195 e a " x=" 68 " y=" 24 " w i d t h="å 411 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t s i z e=" 16 " i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ t i t l e } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" e 7 4 0 4 5 2 a −0179−45 f 5 −87c5−c 1 5 3 3 b 5 6 0 f d 3 " x=" 432 " y=" 60 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ ( new SimpleDateFormat ( $P{ p a t t e r n O f D a t e } ) ) . f o r m a t ( å C a l e n d a r . g e t I n s t a n c e ( ) getTime ( ) ) ] ]

></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ t i t l e > A példa befejezéséhez még azt kell megadnunk, hogy a jelentéskészítő program milyen szerkezettel épül fel, ezt tartalmazza az 5-5. Programlista. A 18 sorig ismert a program A 22-24 sorokban a már bemutatott módon megszerezzük a magyar formátum stringet, amit a 27. sorban adunk át paraméterként A 28 sor közli a jelentéskészítő generátorral, hogy most a 1 2 3 4 5 6 7 8 9 10 11 12 új paraméterünket, ez fogja majd átvenni a megfelelő dátumformázó string értékét. A dátumot a riport title részébe helyeztük el (23-27 sorok). A 26. sor textFieldExpression kifejezése mutatja a megadható kifejezést, ami a pillanatnyi dátumot fogja megjeleníteni a $P{patternOfDate} formátum szerint. <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t . . <p a r a m e t e r name=" p a t t e

r n O f D a t e " c l a s s=" j a v a . l a n g S t r i n g " /> 18 19 20 21 22 23 24 27 28 29 30 Többnyelvű riportok készítése locale változó tartalma szerint (azaz magyar) vegye a $R{.} értékeket A program többi része ismét ismerős az előző példákból, így nem részletezzük. Csak érdekességként tekintsünk rá az 5-6. Programlista programtöredékére is, ahol az adatforrásból érkező HireDate mezőre alkalmazott formázási lehetőségre adtunk példát. // 5−5. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r I 1 8 N F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−I18N . j a s p e r " ; public s t a t i c void testI18NRDBMS ( ) throws E x c e p t i o n { S t r i n g s q l = " s e l e c t ␣ ∗ ␣ from ␣ o r s z a g o k ␣ where

␣ t e r u l e t ␣<␣ ? " ; 58 JasperReports 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 Többnyelvű riportok készítése C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , "å ") ; P r e p a r e d S t a t e m e n t stmt = conn . p r e p a r e S t a t e m e n t ( s q l ) ; stmt . s e t D o u b l e ( 1 , 1 0 0 0 0 0 0 0 ) ; R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ) ; JRDataSource j r d s = new J R R e s u l t S e t D a t a S o u r c e ( r s ) ; JRHelper j h = new JRHelper ( ) ; // L o c a l e l o c a l e = L o c a l e . ENGLISH ; // L o c a l e l o c a l e = L o c a l e .GERMAN; L o c a l e l o c a l e = new L o c a l e ( "hu" , "HU" ) ; ResourceBundle myResources = ResourceBundle . g e t B u n d l e ( " o r s z a g o k T e x t " , l o c a l e ) ; S t r i

n g dateFormat = myResources . g e t S t r i n g ( " dateFormat " ) ; HashMap params = new HashMap ( ) ; params . put ( " p a t t e r n O f D a t e " , dateFormat ) ; params . put ( JRParameter REPORT LOCALE, l o c a l e ) ; j h . makeReport ( j a s p e r I 1 8 N F i l e , params , j r d s ) ; } } rs . close () ; stmt . c l o s e ( ) ; conn . c l o s e ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testI18NRDBMS ( ) ; } 1 // 5 −6. P r o g r a m l i s t a 2 3 $F{ FirstName } + "␣" + $F{LastName} + " ␣was␣ h i r e d ␣on␣ " + 4 ( new SimpleDateFormat ( $P{ patternOf Da te } ) ) . format ( $F{ HireDate } ) + " " 5 </ t e x t F i e l d E x p r e s s i o n> A nyelvfüggő adatformátumok Érdemes megismerni a Java egyszerű, lokalitás függő szövegformázó lehetőségeit, mert nagy hasznát vehetjük akkor, amikor ezeket felhasználjuk riportjaink készítése során. Az

5-7 Programlista ismét a dátumok formázására mutat példát, de a kinézet mintáját nem mi adjuk meg, 1 2 3 4 5 6 7 8 9 10 11 hanem a DateFormat class statikus getDateInstance() gyártómetódus 2. paraméterében lévő locale változó segítségével biztosítjuk a helyes formátum szerinti működést. A példában csak a MEDIUM és FULL szerinti formátumokat teszteltük, de jó pár további, előre programozott eset érhető még el. A példa végén a program futási eredményét is láthatjuk. // 5−7. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t DateFormat ; . import j a v a . u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t D a t e ( ) 59 JasperReports 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 { L o c a l e l o c a l e = L o c a l e .GERMAN; DateFormat d f = DateFormat . g e t D a t e I n s t a n c e ( DateFormat MEDIUM, l o c a l e ) ;

System . out p r i n t l n ( d f f o r m a t (new Date ( ) ) ) ; } } d f = DateFormat . g e t D a t e I n s t a n c e ( DateFormat FULL, l o c a l e ) ; System . out p r i n t l n ( d f f o r m a t (new Date ( ) ) ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) { testDate () ; } F u t á s i kép : 19.012013 Samstag , 1 9 . Januar 2013 A következő példánkban (5-8. Programlista) a NumberFormat osztály segítségével a számok országfüggő formázását tudjuk úgy automatizálni, hogy getIntegerInstance() segítségével le1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 Többnyelvű riportok készítése kérjük az adott lokalitás szokásos formázási szokását. A testInteger() metódusban ezt megtesszük a német, angol és magyar esetre egyaránt, majd a futási eredményt is láthatjuk // 5−8. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e

x t DateFormat ; . import j a v a . u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t I n t e g e r ( ) { L o c a l e l o c a l e = L o c a l e .GERMAN; NumberFormat n f = NumberFormat . g e t I n t e g e r I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; l o c a l e = L o c a l e . ENGLISH ; n f = NumberFormat . g e t I n t e g e r I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; } } l o c a l e = new L o c a l e ( "hu" , "HU" ) ; n f = NumberFormat . g e t I n t e g e r I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) { testInteger () ; } F u t á s i kép : 1.234567 1 ,234 ,567 1 234 567 60 JasperReports A testDecimal() tesztmetódus (5-9. Programlista) abban különbözik az előző példától, hogy itt a szám

formázására mi adhatjuk meg a formátum maszkot, amihez a DecimalFormat 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Többnyelvű riportok készítése osztályt tudjuk segítségül hívni. A main() metódusban 3 formázási esetet is kipróbáltunk a 1234567 számra, aminek eredményét is közöltük. // 5−9. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t DateFormat ; . import j a v a . u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t D e c i m a l ( S t r i n g p a t t e r n ) { NumberFormat n f = new DecimalFormat ( p a t t e r n ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; } } public s t a t i c void main ( S t r i n g [ ] a r g s ) { t e s t D e c i m a l ( "#,##0" ) ; t e s t D e c i m a l ( "#,##0.00" ) ; t e s t D e c i m a l ( " u00A4#,##0.00" ) ; } F u t á s i kép : 1 234 567 1

234 567 ,00 Ft1 234 567 ,00 Amennyiben pénzügyi számokat szeretnénk formázni, úgy abban a testCurrency() (5-10. Programlista) megértése siet a segítségünkre 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 // 5 −10. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t DateFormat ; . import j a v a . u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t C u r r e n c y ( ) { L o c a l e l o c a l e = L o c a l e .GERMAN; NumberFormat n f = NumberFormat . g e t C u r r e n c y I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; l o c a l e = L o c a l e . ENGLISH ; n f = NumberFormat . g e t C u r r e n c y I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; l o c a l e = new L o c a l e ( "hu" , "HU" ) ; n f = NumberFormat . g e t C u r r e n c y I n s t

a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 1234567 ) ) ; 61 JasperReports 26 27 28 29 30 31 32 33 34 35 36 37 Többnyelvű riportok készítése } } public s t a t i c void main ( S t r i n g [ ] a r g s ) { testCurrency () ; } F u t á s i kép : 1.234567 ,00 1 ,234 ,567.00 1 2 3 4 5 6 7 Ft Az 5-11. Programlista testTime() metódusa DateFormat class használatával megszerezve a az óra/perc/másodperc információt tudja meg- formázást végző df objektumot. jeleníteni nyelvfüggő módon, a már megismert 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // 5 −11. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t DateFormat ; . import j a v a . u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t T i m e ( ) { L o c a l e l o c a l e = L o c a l e .GERMAN; DateFormat d f = DateFormat . g e t

T i m e I n s t a n c e ( DateFormat SHORT, l o c a l e ) ; System . out p r i n t l n ( d f f o r m a t (new Date ( ) ) ) ; d f = DateFormat . g e t T i m e I n s t a n c e ( DateFormat LONG, l o c a l e ) ; System . out p r i n t l n ( d f f o r m a t (new Date ( ) ) ) ; } } l o c a l e = new L o c a l e ( "hu" , "HU" ) ; d f = DateFormat . g e t T i m e I n s t a n c e ( DateFormat MEDIUM, l o c a l e ) ; System . out p r i n t l n ( d f f o r m a t (new Date ( ) ) ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) { testTime ( ) ; } F u t á s i kép : 16:26 1 6 : 2 6 : 3 4 GMT 16:26:34 A testPercent() (5-12. Programlista) a százalékok kezelésére ad egy példát 1 2 3 4 5 6 // 5 −12. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t DateFormat ; . 62 JasperReports 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 import j a v a .

u t i l L o c a l e ; public c l a s s MessageFormatTest { public s t a t i c void t e s t P e r c e n t ( ) { L o c a l e l o c a l e = L o c a l e .GERMAN; NumberFormat n f = NumberFormat . g e t P e r c e n t I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 0 2 5 ) ) ; l o c a l e = L o c a l e . ENGLISH ; n f = NumberFormat . g e t P e r c e n t I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 0 2 5 ) ) ; } } l o c a l e = new L o c a l e ( "hu" , "HU" ) ; n f = NumberFormat . g e t P e r c e n t I n s t a n c e ( l o c a l e ) ; System . out p r i n t l n ( n f f o r m a t ( 0 2 5 ) ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) { testPercent () ; } F u t á s i kép : 25% 25% 25% A szövegelemek előállításának másik fontos fajtája a szövegrészletek helyettesítése, amit testMessageFormat() teszteset (5-13. Programlista) ismertet meg velünk A megoldás

alapja a Java MessageFormat osztály, ami egy szövegmintát tartalmaz, benne tetszőleges számú feloldatlan, {<number>} jellel jelölt pozícióval. Amikor meghívjuk a format() metódust, akkor átadjuk a pozíciókba helyettesítendő értékeket is, így előáll a végleges szöveg, ahogy a futási 1 2 3 4 5 6 7 8 9 10 11 12 13 14 Többnyelvű riportok készítése kép is mutatja. Ezzel a módszerrel tehát úgy tehetünk össze szövegeket, hogy nem kell sok string összefűző műveletet végezni, ami jelentősen rontani szokta a program olvashatóságát. Érdekes felhasználása lehet például az SQL parancsok összeállítása is, ugyanis sokszor találkozunk azzal a gyakorlattal, hogy azt több soron rakja össze a programozó. Esetünkben egy jó jelölt lehet a query string is. // 5 −13. P r o g r a m l i s t a : MessageFormatTest j a v a package o r g . c s t e s t ; import j a v a . t e x t MessageFormat ; . import j a v a . u t i l L o c a l e ;

public c l a s s MessageFormatTest { public s t a t i c void t e s t M e s s a g e F o r m a t ( ) { S t r i n g r e s u l t = MessageFormat . f o r m a t ( "Az␣ {0} ␣ á r a : ␣ { 1 } ␣Ma␣ van : ␣ { 2 , d a t e } " , " alma " , 3 2 , å new Date ( ) ) ; System . out p r i n t l n ( r e s u l t ) ; 63 JasperReports 15 16 17 18 19 20 21 22 23 24 Többnyelvű riportok készítése } } public s t a t i c void main ( S t r i n g [ ] a r g s ) { testMessageFormat ( ) ; } F u t á s i kép : Az alma á r a : 3 2 . Ma van : 2 0 1 3 0 1 2 0 vetni. A bal oldalon látható dátum formázó string csak az érdekesség kedvéért maradt a riEljutva idáig megtanultuk adatainkat or- portban. szágfüggő módon átalakítani szöveges formátumra. Befejezésül az Orszagok-I18Njrxml riport tervbe (5-14 Programlista) betesszük a terulet oszlop nyelvfüggően formázott változatát Nézzük meg az új jrxm fájlt, aminek csak a változást tartalmazó

részét szúrtuk be! Az 1. újdonság a 7 sorba felvett formatInteger paraméter, ami NumberFormat típusú A 2 új elem a 49-53 sorok között látható, megváltoztatott textField komponens. A textFieldExpression résznél (52 sor) jól látható, ahogy a paraméterül kapott formatInteger objektumnak meghívtuk a format() metódusát a $F{TERULET} értékre. Az így megváltoztatott riport elkészült változatát az 5.3 ábra mutatja Láthatjuk, ahogy a terület oszlop számai szépen formázva jelennek meg. Az előző példából maradt címsorban 5.3 ábra: Országfüggő riport megjelenített dátumra is érdemes egy pillantást Lokális adatformátumú riport 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 5 −14. P r o g r a m l i s t a : Orszagok−I18N j r x m l <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t . . <p a r a m e t e r name=" p a t t e r n O f D a t e " c l a s s=" j a v a . l a n

g S t r i n g " /> <p a r a m e t e r name=" f o r m a t I n t e g e r " c l a s s=" j a v a . t e x t NumberFormat " /> <q u e r y S t r i n g l a n g u a g e="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> . 19 20 21 22 23 24 64 < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < t i t l e> <band h e i g h t=" 93 " s p l i t T y p e=" S t r e t c h "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 69 af5ddd −3722−48b7 −8620 −5680547195 e a " x=" 68 " y=" 24 " w i d t h="å 411 " h e i g h t=" 20 " /> <t e x t E l e m e n t> <f o n t s i z e=" 16 " i s B o l d=" t r u e " /> </ t e x t E l e m e n t> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $R{ t i t l e } ] ]

></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> JasperReports 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 . </ band> </ t i t l e > Többnyelvű riportok készítése <r e p o r t E l e m e n t u u i d=" e 7 4 0 4 5 2 a −0179−45 f 5 −87c5−c 1 5 3 3 b 5 6 0 f d 3 " x=" 432 " y=" 60 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ ( new SimpleDateFormat ( $P{ p a t t e r n O f D a t e } ) ) . f o r m a t ( å C a l e n d a r . g e t I n s t a n c e ( ) getTime ( ) ) ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < d e t a i l> <band h e i g h t=" 40 " s p l i t T y p e=" S t r e t c h "> < t e x t F i e l d> <r e p o r t E l e

m e n t u u i d=" a2856d02 −9 c e f −48e3 −9240− c f 0 a 1 1 b 7 6 4 8 8 " x=" 24 " y=" 12 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{ORSZAG} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 5 e 6 f f 3 5 e −58db−418b−9bcb−e 4 f 4 0 4 4 1 8 5 e 0 " x=" 142 " y=" 12 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOVAROS} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d i s S t r e t c h W i t h O v e r f l o w=" t r u e "> <r e p o r t E l e m e n t u u i d=" be169129 −86a9 −47c3 −829a −4196 d

e c f 2 7 1 c " x=" 261 " y=" 12 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{FOLDR HELY} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" a583d337 −91a5−4ee 2−b 1 c f −3b c d 4 5 4 2 9 f 8 a " x=" 379 " y=" 12 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" R i g h t " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ P{ f o r m a t I n t e g e r } . f o r m a t ( $F{TERULET} ) ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ d e t a i l> . </ j a s p e r R e p o r t> A jelentés elkészítését végző programot az 5-15. Programlista

tartalmazza. A testI18NRDBMS() metódust már ismerjük, a változás a 30-31 sorokban van, ahol létrehozunk egy NumberFormat típusú nf objektumot, majd 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 formatInteger néven betesszük azt a riport paraméterei közé. Emlékeztetőül itt is kiemeljük, hogy ezt a paramétert a jrxml-ben ezzel a hívással használjuk: $P{ f o r m a t I n t e g e r } . f o r m a t ( $F{TERULET} ) // 5 −15. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; . public c l a s s T e s t O r s z a g o k R i p o r t { s t a t i c S t r i n g j a s p e r I 1 8 N F i l e = " /home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/Orszagok−I18N . j a s p e r " ; public s t a t i c void testI18NRDBMS ( ) throws E x c e p t i o n { // L o c a l e l o c a l e = L o c a l e . ENGLISH ; // L o c a l e l o c a l e = L o c a l e .GERMAN; L o c a l e l o c a l e = new L o c a l e (

"hu" , "HU" ) ; ResourceBundle myResources = ResourceBundle . g e t B u n d l e ( " o r s z a g o k T e x t " , l o c a l e ) ; S t r i n g dateFormat = myResources . g e t S t r i n g ( " dateFormat " ) ; S t r i n g s q l = " s e l e c t ␣ ∗ ␣ from ␣ o r s z a g o k ␣ where ␣ t e r u l e t ␣<␣ ? " ; C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , "å ") ; P r e p a r e d S t a t e m e n t stmt = conn . p r e p a r e S t a t e m e n t ( s q l ) ; stmt . s e t D o u b l e ( 1 , 1 0 0 0 0 0 0 0 ) ; 65 JasperReports 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 Többnyelvű riportok készítése R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ) ; JRDataSource j r d s = new J R R e s u l t S e t D a t a S o u r c e ( r s ) ; JRHelper j h = new JRHelper ( ) ;

HashMap params = new HashMap ( ) ; params . put ( " p a t t e r n O f D a t e " , dateFormat ) ; params . put ( JRParameter REPORT LOCALE, l o c a l e ) ; NumberFormat n f = NumberFormat . g e t I n t e g e r I n s t a n c e ( l o c a l e ) ; params . put ( " f o r m a t I n t e g e r " , n f ) ; j h . makeReport ( j a s p e r I 1 8 N F i l e , params , j r d s ) ; rs . close () ; stmt . c l o s e ( ) ; conn . c l o s e ( ) ; } } public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testI18NRDBMS ( ) ; } Most állítsuk be a locale változót erre az ér- juk, hogy a dátum és a számok formátuma is váltékre és futassuk le a riportot! tozott. A számok tagolása hasonló a magyarhoz, L o c a l e l o c a l e = L o c a l e .GERMAN; azonban szóköz helyet „.’ karakter található Az 5.5 ábra az angol változat, ahol a számok „ ,” karakterrel választódnak el egymástól. 5.4 ábra: Német riport Az eredményt az 5.4

ábra mutatja Láthat- 66 5.5 ábra: Angol riport JasperReports 6. Változók és kifejezések használata Változók és kifejezések használata Ebben a részben a JasperReports 2 hatékony eszközét vizsgáljuk meg. Az egyik a változók használata, ami nélkül sok feladat megoldása sokkal nehezebb vagy esetleg lehetetlen lenne A másik a kifejezések alkalmazása, amiket már eddig is használtunk, azonban megtanuljuk, hogy sokkal többre is képesek. Van néhány hely a jrxml fájlon belül, ahol A változók kifejezéseket adhatunk meg: Alapismeretek • <textFieldExpression> • <variableExpression> • <initialValueExpression> • <groupExpression> • <printWhenExpression> • <imageExpression> Egy kifejezés változókból, paraméterekből és természetesen adatforrás mezőkből álló műveletek és metódushívások kombinációja lehet. Első lépésként tekintsük át a változókat egy kicsit részletesebben is,

utána pedig elmélyedünk a kifejezések világában 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 Egy riportban tetszőleges számú változót deklarálhatunk, aminek megadási módját a 6-1. Programlista jrxml töredéke mutatja be A példában a Nepsuruseg, var 1 és var 2 egy-egy változó, amelyek alapvetően mindig valamilyen kifejezésnek a névvel hivatkozott tárolói A nevet a name attribútumnál adjuk meg, amit a class megadása követ. Minden változó valamilyen Java osztályhoz tartozik, de természetesen a kalkulációs műveletek csak a szám típusokra fognak működni. A variableExpression az a tag, ahol egy Java kifejezés adható meg. A változó értékének kalkulációja az itt megadott kifejezés szerint fog történni. // 6 −1. P r o g r a m l i s t a : 2 v á l t o z ó d e k l a r á s l á s a . <v a r i a b l e name=" Nepsuruseg " c l a s s=" j a v a . l a n g Double "> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[

$ F{NEPESSEG} . d o u b l e V a l u e ( ) / $F{TERULET} å d o u b l e V a l u e ( ) ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> <v a r i a b l e name=" var 1 " c l a s s=" j a v a . l a n g I n t e g e r " r e s e t T y p e="None"> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ 2 ∗ $V{PAGE NUMBER} ] ] ></ v a r i a b l e E x p r e s s i o n> <i n i t i a l V a l u e E x p r e s s i o n>< ! [CDATA[ ] ] ></ i n i t i a l V a l u e E x p r e s s i o n> </ v a r i a b l e> <v a r i a b l e name=" var 2 " c l a s s=" j a v a . l a n g I n t e g e r " r e s e t T y p e="None"> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ 2 ] ] ></ v a r i a b l e E x p r e s s i o n> <i n i t i a l V a l u e E x p r e s s i o n>< ! [CDATA[ 5 ] ] ></ i n i t i a l V a l u e E x p r e s s i o n> </ v a r i a b l

e> . 67 JasperReports Változók és kifejezések használata A Nepsuruseg változó a népesség és a terület adatforrás mezők hányadosát tárolja (5. sor) A var 1 az aktuális oldal számának a kétszeresét adja (9. sor), míg a var 2 kifejezése a 2 értékű konstans (14. sor) Az initialValueExpression címke a változó induló értékének megadását biztosítja a riportkészítés megkezdésekor. A 61 ábra mutatja a változókra beállítható property lehetőségeket, amit mindenképpen meg kell értenünk. A Reset type egyes lehetőségei a következőek: hogy a Group-okra alkalmazott beállításokat – noha talán ez a legfontosabb – csak a következő cikkben tárgyaljuk. Az Increment type segítségével nagyon pontosan meg tudjuk adni azt a pillanatot, amikor a változó értékét változtatni, halmozni szükséges. Ugyanazokra az értékekre állíthatjuk, mint a Reset type-ot. • None: Ekkor a változót a riport készítése során sosem

állítjuk alapértékre (No reset). • Report: A riport készítése során soha nem lesz aggregálva a változó. • Report: Ekkor a változó egy alkalommal, a riport elkészítés elején inicializálódik. Ez az alapértelmezett működési mód. • Page: A változó minden oldal megkezdésekor újra inicializálódik. • None: Minden sornál megtörténik az inkrementálás. • Page: A változó minden oldal megkezdésekor lesz növelve. • Column: A változó minden új oszlop megkezdésekor halmozódik. • Group: A következő – group-okkal foglalkozó – fejezetben részletesen bemutatjuk. • Column: A változó minden oszlop megkezA Calculation lehetséges értékeit (Count=számlálás, désekor újra inicializálódik. Sum=összegzés, .) a 2 cikkben már bemutat• Group: Egy új csoporthoz érve, annak tuk megkezdésekor történik a reset. Ilyenkor a Reset group megadása is kötelező, hiszen Beépített riport változók egy riport adatai több szempont

szerint A JasperReports tartalmaz néhány előre létrecsoportosulhatnak. hozott riport változót, amit érdemes röviden áttekintenünk. 6.1 ábra: A változó tulajdonságai A következő pontokban gyakori használati eseteket mutatunk be, azonban megjegyezzük, 68 • PAGE NUMBER: Ez a változó mindig a pillanatnyi oldalszámot tartalmazza, így értéke az 1. oldalon 1, a 12 oldalon 12. Van egy érdekes használati lehetősége, amikor az aktuális oldal / összes oldal értéket szeretnénk megjeleníteni a lapon (például annak footer részében) A textField vizuális riport komponens rendelkezik egy evalutionTime jellemzővel. Amennyiben a PAGE NUMBER értékét 2 mezőbe is betesszük (legyen Field Act és Field Pages), akkor az 1. mező értékét JasperReports • • • • • 1 2 3 4 5 now, a 2. mezőét Report értékre állítva a Egyszerű soronkénti kifejezés kívánt hatást érjük el. A 6-1. Programlistán mutatott 3 riport váltoCOLUMN NUMBER: Az

éppen feldol- zót kitettük a detail sávba a 6-2 Programlista gozás alatt lévő oszlop száma. Példa: szerint Ezzel most minden adatforrás rekordAmennyiben a jelentés 3 oszlopos, úgy ér- hoz 2 sor tartozik a riportban (a 2 sor tartalmazza a 3 db változónkat és azok címkéjét), tékei: 1, 2, 3. ahogy azt a 6.2 ábra mutatja A jrxml részletREPORT COUNT : Az adatforrásból ben az egyedüli újdonság a 4 sorban található jött, feldolgozott sorok száma. pattern, ugyanis a 2 double hányadosát 2 tizedesPAGE COUNT : Az aktuális lapon eddig jegy hosszig jelenítjük meg. A változók jelenlegi beállításai (6.1 ábra) azt teszik lehetővé, hogy feldolgozott rekordok száma. minden egyes új adatsor esetén a változók kiérCOLUMN COUNT : Az aktuális oszlop- tékelődnek és ezt az értéket meg is kapják, ez nál eddig feldolgozott rekordok száma. fog megjelenni. Itt most semmilyen halmozásra nincs szükségünk, hiszen csak a sorokra vonatGroupName COUNT : Az

adott groupkoztatott számított adatokat szeretnénk kiírni. ra vonatkozó eddig feldolgozott rekordok száma. // 6 −2. P r o g r a m l i s t a : 3 r i p o r t mező . 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 Változók és kifejezések használata . < t e x t F i e l d p a t t e r n=" ###0.00;(###000) "> <r e p o r t E l e m e n t u u i d=" 812 f f 2 c 8 −d729 −49b0−b97d −825 e 4 2 6 8 c d 2 2 " x=" 105 " y=" 50 " w i d t h=å " 42 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{ N e p s u r u s e g } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 5 a f 8 7 8 b 2 −4702−45d7−9beb−2b 7 e 9 4 7 e d 4 6 3 " x=" 273 " y=" 50 " w i d t h=å " 73

" h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" R i g h t " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{ var 1 } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 0 b9a19be−fdb1 −4b4d−8e99 −0f d 3 a 8 1 a 9 a 1 b " x=" 444 " y=" 50 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{ var 2 } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" 6 d87e249 −1e09 −4f 2 5 −8702−6 b 2 c 2 9 7 a 6 1 e 0 " x=" 24 " y=" 50 " w i d t h="å 66 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x

t>< ! [CDATA[ N é p s ű r ű s é g : ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" 02007466 − be21 −4182− b a f a −9b d a 9 4 4 f e b 8 2 " x=" 160 " y=" 50 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" R i g h t " /> <t e x t>< ! [CDATA[ var 1= ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" f 7 2 5 c c 0 6 −9408−468c−b41b−f 4 1 c 8 2 d f 2 d 6 8 " x=" 371 " y=" 50 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[ var 2= ] ] ></ t e x t> </ s t a t i c T e x t> A Nepsuruseg ezzel mindig az adott sorra, rint működik, azaz az egyes oldalakon végig a 2, azaz

adott országra számított érték lesz. A 4, , 24 lesz az értéke (egy lapon belül persze var 1 a 2*$V{PAGE NUMBER} kifejezés sze- ugyanaz az érték), ugyanis az egész jelentés 12 69 JasperReports oldalas. A var 2 értéke csak egy konstans, ami most a riport minden sorában a 2 értéket veszi fel. Aki az eddigieket értette, annak bizonyára egyből érthető, hogy minden más változatlanul hagyása mellett a Reset type=Report esetén is ugyanez lesz a végeredmény. Változók és kifejezések használata lation=Sum és Reset type=Report beállítást végezzük el a var 1 és var 2 változókon. A következő eredményt fogjuk kapni az egyes változókra: 1. var 1 : (a) 1. oldal: 2, 4, 6, , 14 (halmozás 2x1=2 hozzáadásával) (b) 2. oldal: 18, 22, 26, , 46 (halmozás 2x2=4 hozzáadásával) (c) 3. oldal: 52, 58, 64, (halmozás 2x3=6 hozzáadásával) 2. var 2 : (a) 1. oldal: 2, 4, 6, , 14 (b) 2. oldal: 16, 18, 20, 6.2 ábra: Egyszerű kifejezés - Riport részlet

Számlálás Most állítsuk be a var 1 és var 2 változók Calculation jellemzőjét Count értékre (a Reset type=Riport maradt). Az így elkészített riport mindkét változóra soronként 1-gyel nagyobb értéket ír ki. Ez azt jelenti, hogy minden egyes sorra mindkét változó értéke ez a sorozat lesz: 1, 2, 3, ., 89 A következő kísérlet legyen csak annyi változtatás, hogy a Reset type=Page beállítást csináljuk. Ekkor valóban azt kapjuk, amit vártunk, azaz minden oldalon elölről kezdődik az 1, 2, . sorozat Főösszegek Most vizsgáljuk meg a másik tipikus aggregálási műveletet, az összegzést! Ehhez a Calcu70 Befejezésül nézzük meg a Calculation=Sum és Reset type=Page beállítást! Ilyenkor minden lapkezdéskor reset történik mindkét változóra, a jelentés soronkénti értékei pedig így alakulnak: 1. var 1 : (a) 1. oldal: 2, 4, 6, , 14 (halmozás 2x1=2 hozzáadásával) (b) 2. oldal: 4, 8, 12, , 32 (halmozás 2x2=4 hozzáadásával) (c) 3.

oldal: 6, 12, 18, (halmozás 2x3=6 hozzáadásával) 2. var 2 : (a) 1. oldal: 2, 4, 6, , 14 (b) 2. oldal: 2, 4, 6, JasperReports Változók és kifejezések használata A kifejezések összeépítése Az if-then-else megvalósítása Egy JasperReports kifejezés operandusai azok az objektumok lehetnek, amik a 6.3 ábra alsó részén láthatóak Amit látunk, az egy iReport segédeszköz a kifejezések gyors összekattintására, de természetesen ezt kézzel írva is megadhatjuk. Az ablak például akkor bukkan fel, amikor a 61 ábra Variable Expression melletti „” nyomógombra kattintunk. Ugyanakkor ilyen lehetőség több is van, hiszen a vizuális felületen sok olyan pont van, ahol éppen egy kifejezést lehet megadni. Látható, hogy a mezők, változók és paraméterek, illetve ezek metódushívásaival visszakapott értékek alkotják a kifejezésben résztvevő tagokat. A tagok között a Java mindegyik operátorát használhatjuk A kifejezések azért nagyon

fontosak, mert ezzel is dinamikusan lehet adatokat előállítani a jelentés számára. Vegyük példaként az <imageExpression> címkét! Itt egy képfájl útvonalát adhatjuk meg, azonban azt nem kell statikusan beégetni a jrxml fájlba, esettől függően akár soronként más-más kép jelenhet meg, attól függően, hogy az ide definiált sztring kifejezés éppen melyik képfájl nevét adta vissza. Ebben a pontban szeretnénk elmélyíteni a kifejezések használatának megértését, ezért 6.3 ábra: Kifejezések összeállítása 1. először készítünk egy hasznos osztályt (JasperIf ), 2. majd bemutatjuk annak használatát egy összetett kifejezés részeként. A JasperIf osztály létrehozása A JasperIf osztály (6-3. Programlista) céljának és működésének megértéséhez először nézzük meg a 89-100 sorok közötti main() metódust, ami példát mutat a használatára A cél az, hogy egy láncolt kifejezéssel le tudjunk írni egy több

elágazásos if utasítást. Itt jegyezzük meg, hogy ehhez a builder tervezési minta egy implementációs technikáját használjuk, ahol az egyes láncszemek azért fűzhetőek fel egymás utáni metódushívásokkal, mert mindegyik a this objektumot adja vissza. Ez alól csak a lánc végén meghívott evaluate() a kivétel, ami – gondolva a riportban való használat céljára – most Stringet ad vissza. A 93 sor a és b változója csak a példa kedvéért lett felvéve, velük fogalmazzuk meg a 95. és 98 sorokban lévő használati esetek feltételeit A használat jobb megértéséhez nézzük most a 98. sorban megfogalmazott kifejezést! A j változó egy JasperIf objektumra mutat, amit a 91. sorban hoztunk létre Balról nézve az 1. metódushívás a jif(a < b), ami egy JasperIf objektumot ad vissza, ez pontosabban maga a j által mutatott, már említett objektum (más szavakkal ez a this). A 2 hívás a jthen("a < b"), ami az if igaz értéke esetén

visszaadott String értékét állítja be, miközben a visszatérési érték megint a j referencia. A 3 hívás a j változónkra vonatkozó jelseif(a == b, "a == b"), ahol ennek igazsága mellett (1. paraméter) visszaadandó String értéket (2. paraméter) definiáljuk A 4 metódus ugyanígy működik A 71 JasperReports lánc végén lévő evaluate() végül elvégzi a számítást és a megfelelő ághoz tartozó String értéket fogja az s-hez rendelni. A program futtatása után ez a 2 sor jelenik meg a képernyőn: a >= b a > b Változók és kifejezések használata • jthen: eltárolja az ifCondition==true esetre visszaadandó Stringet. • jelse: eltárolja az else esetre visszaadandó Stringet. A JasperIf class egy szép példa az építő • jelseif : egy ElseIf segédosztályokból álló minta használatára. A konstruktor (19-22 so(boolean, String párok) listát épít rok) előállít egy induló objektumot, amit utána az építő

metódusokkal alakítjuk a véglegesre: Az 53-69 sorok között található evaluate() a • jif : eltárolja a paraméterként megadott lo- builder metódusok által kialakított JasperIf obgikai kifejezés értékét (az ifCondition vál- jektumot értékeli ki, azaz végül azt a Stringet tozóba) adja vissza, ami az igaz ágnak felel meg. 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 // 6−3. P r o g r a m l i s t a : J a s p e r I f j a v a package o r g . c s t e s t ; import j a v a . u t i l A r r a y L i s t ; import j a v a . u t i l L i s t ; /∗ ∗ ∗ B u i l d e r minta ∗/ public c l a s s J a s p e r I f { private private private private Boolean i f C o n d i t i o n ; L i s t <E l s e I f > e l s e i f C o n d i t i o n s ; S t r i n g thenStatement ; String elseStatement ; public J a s p e r I f ( ) { t h i s . e l s e i f C o n d i t i o n s = new A r r a y L i s t <E l s

e I f >() ; } public J a s p e r I f j i f ( Boolean i f C o n d ) { this . i f C o n d i t i o n = ifCond ; return t h i s ; } public J a s p e r I f j t h e n ( S t r i n g then ) { t h i s . t h e n S t a t e m e n t = then ; return t h i s ; } public J a s p e r I f j e l s e ( S t r i n g e l s e S t a t e m e n t ) { this . elseStatement = elseStatement ; return t h i s ; } public J a s p e r I f j e l s e i f ( Boolean e l s e i f , S t r i n g e l s e i f S t a t e m e n t ) { t h i s . e l s e i f C o n d i t i o n s add (new E l s e I f ( e l s e i f , e l s e i f S t a t e m e n t ) ) ; 72 JasperReports 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 } Változók és kifejezések használata return t h i s ; public S t r i n g t o S t r i n g ( ) { return e v a l u a t e ( ) ; } private S t r i n g e v a l u a t e ( ) { if ( ifCondition )

{ return t h e n S t a t e m e n t ; } else { for ( E l s e I f e l s e i f : e l s e i f C o n d i t i o n s ) { i f ( e l s e i f . cond ) { return e l s e i f . s t a t e m e n t ; } } } return e l s e S t a t e m e n t ; } private c l a s s E l s e I f { private Boolean cond ; private S t r i n g s t a t e m e n t ; } E l s e I f ( Boolean cond , S t r i n g s t a t e m e n t ) { t h i s . cond = cond ; this . statement = statement ; } /∗ ∗ ∗ Only t e s t ∗ ∗ @param a r g s ∗/ public s t a t i c void main ( S t r i n g [ ] a r g s ) { J a s p e r I f j = new J a s p e r I f ( ) ; int a = 5 , b = 3 ; S t r i n g s = j . j i f ( a < b ) j t h e n ( " a ␣<␣b" ) j e l s e ( " a ␣>=␣b" ) e v a l u a t e ( ) ; System . out p r i n t l n ( s ) ; } } s = j . j i f ( a < b ) j t h e n ( " a ␣<␣b" ) j e l s e i f ( a == b , " a ␣==␣b" ) j e l s e i f ( a > b , " a ␣>␣b" ) å

evaluate () ; System . out p r i n t l n ( s ) ; a JasperReportsban történő használatát! Az Orszagok-VAR.jrxml (6-4 Programlista) fonMost, hogy rendelkezünk egy egészen csinos tos változtatásokat tartalmaz, nézzük meg őket if-then-else lehetőséggel, próbáljuk ki ennek A JasperIf osztály használata 73 JasperReports egyesével: 1. Egy import utasítás (6 sor): A JasperIf osztályt használjuk, ezért importálni kell. Fontos, hogy az iReport Tools Options Classpath fülnél felvettük a classpathhoz az elérhetőségét is. 2. Egy új sizeSelector nevű paraméter (8 sor): Ez a paraméter azt vezérli majd, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 Változók és kifejezések használata hogy a kifejezésben mely terület mérethatárnál kezdődjön a „Nagy” ország. 3. A TERULET textField (18 sor): Az ország mérete helyett most ezzel a kifejezéssel csak annyit írunk ki, hogy „Nagy” vagy „Kicsi”: new J a s p e r I f ( ) ) . j i

f ( $F{TERULET}>$P{ s i z e S e l e c t o r å } ) . j t h e n ( " Nagy " ) j e l s e ( " K i c s i " ) e v a l u a t e ( ) // 6 −4. P r o g r a m l i s t a : Orszagok−VAR j r x m l ? xml v e r s i o n=" 1 . 0 " e n c o d i n g="UTF−8"?> <j a s p e r R e p o r t . . <i m p o r t v a l u e=" o r g . c s t e s t ∗ " /> . <p a r a m e t e r name=" s i z e S e l e c t o r " c l a s s=" j a v a . l a n g I n t e g e r " /> <q u e r y S t r i n g l a n g u a g e="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> . < d e t a i l> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" a583d337 −91a5−4ee 2−b 1 c f −3b c d 4 5 4 2 9 f 8 a " x=" 331 " y=" 12 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t t e x t A l i g n m e

n t=" R i g h t " /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ ( new J a s p e r I f ( ) ) . j i f ( $F{TERULET}>$P{ s i z e S e l e c t o r } ) å . j t h e n ( " Nagy " ) j e l s e ( " K i c s i " ) e v a l u a t e ( ) ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ d e t a i l> . <j a s p e r R e p o r t> A riportot a 6-5. Programlista kódjával ké- részlet Nézzük meg, hogy a terület oszlop alatt szíthetjük el, ahol látható a sizeSelector paramé- az eddigi számértékek helyett most a kíván 2 szó ter értékének az átadása is. Az eredményt a 64 valamelyike jelenik meg! ábra mutatja, ami a teljes riportból kivágott kis 1 2 3 4 5 6 7 8 9 10 11 12 // 6−5. P r o g r a m l i s t a : T e s t O r s z a g o k R i p o r t j a v a package o r g . c s t e s t ; public c l a s s T e s t O r s z a g o k R i p o r t { . public s t a t i c void testRDBMS ( ) throws

E x c e p t i o n { S t r i n g s q l = " s e l e c t ␣ ∗ ␣ from ␣ o r s z a g o k ␣ where ␣ t e r u l e t ␣<␣ ? " ; C o n n e c t i o n conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , å "" ) ; P r e p a r e d S t a t e m e n t stmt = conn . p r e p a r e S t a t e m e n t ( s q l ) ; stmt . s e t D o u b l e ( 1 , 1 0 0 0 0 0 0 0 0 ) ; R e s u l t S e t r s = stmt . e x e c u t e Q u e r y ( ) ; JRDataSource j r d s = new J R R e s u l t S e t D a t a S o u r c e ( r s ) ; 13 14 15 16 17 18 19 20 21 HashMap params = new HashMap ( ) ; params . put ( " s i z e S e l e c t o r " , 1 0 0 0 0 0 ) ; J a s p e r F i l l M a n a g e r . f i l l R e p o r t T o F i l e ( j a s p e r V a r F i l e , j r p r i n t F i l e , params , j r d s ) ; 74 JasperReports 22 23 24 25 26 27 28 29 30 31 . } } Változók és kifejezések használata rs

. close () ; stmt . c l o s e ( ) ; conn . c l o s e ( ) ; public s t a t i c void main ( S t r i n g [ ] a r g s ) throws E x c e p t i o n { testRDBMS ( ) ; } 6.4 ábra: Kifejezés - Kicsi és Nagy ország Az ant script használatához is ki kell egészí- rás persze alapvető input adat, azonban a kifejetenünk a build.xml fájlt, hiszen az ant compile zések használatával szinte minden adatot szárigényelni fogja a JasperIf osztályt maztatni vagy transzformálni tudunk. Kevés <path i d =" c l a s s p a t h "> olyan riportkészítő eszköz létezik amelyik ilyen <p a t h e l e m e n t l o c a t i o n ="./"/ > <p a t h e l e m e n t l o c a t i o n ="$ { c l a s s e s . d i r }"/> eleganciával teszi lehetővé a jelentés tartalmá<p a t h e l e m e n t l o c a t i o n ="/ o p t / j a v a / c l a s s e s "/> < f i l e s e t d i r ="$ { l i b . d i r }"> nak az összeállítását. A

későbbiekben majd még <i n c l u d e name ="∗∗/∗. j a r "/> </ f i l e s e t > arra is látunk példát, hogy a kifejezésekkel mi</path> lyen módon lehet az elkészült dokumentumainkat formázni, esetfüggő külalakkal ellátni (például a kritikus számok piros háttérrel jelenjenek Záró gondolatok meg). A kifejezések természetesen bármilyen táEbben a részben ismét egy hatékony eszközt is- voli hívást is tartalmazhatnak, például egy tőzsmertünk meg A riport generálása során – ahogy dei jegyzéskód helyett annak nevét írjuk ki, amit láttuk is – bármelyik adatelem egy kifejezésen egy webservice segítségével szereztünk meg. keresztül is bekerülhet a riportba. Az adatfor- 75 JasperReports 7. Az adatok csoportokba foglalása Az adatok csoportokba foglalása Amikor réges régen elkezdtem foglalkozni az informatikával, egy nagy számítóközpontban dolgoztam. Rengeteg nyomtatott tabló készült és

ezeket a programozók „kontroll” vagy „összegfokozatos” listáknak nevezték. A lényege mindegyiknek az volt, hogy az adatsorokat logikailag csoportokba foglalta, miközben annak vég és részösszegeit is feltüntette. Most azt nézzük meg, hogy mindezt milyen módon lehet megvalósítani JasperReportsban. Egy egyszerű csoportosítás Az orszagok adatbázis táblára és az első Orszagok.jrxml riportunkra alapozva most készítünk egy olyan jelentést (a design template neve Orszagok-GRP.jrxml lesz), ami kiegészül a GDP és ország kategória oszlopokkal. A feladat az lesz, hogy a lista 1 összegfokozatot tartalmazzon, amit jelen esetben a kategória szerinti csoportosítás fog képezni. A kategoriaGroup csoport létrehozása 7.1 ábra: Egy új riport 76 Első lépésként meg kell terveznünk a 7.3 ábra által mutatott jelentés template-et. A sima 6 oszlopos riportból indulunk ki. Menjünk az egérrel a Report Inspector (71 ábra) gyökér eleméhez

(Orszagok-GRP ) és a jobb egérgombot megnyomva válasszuk ki az Add Report Group funkciót. Egy varázsló bekéri tőlünk a group nevét (ez lett a kategoriaGroup) és a csoportosító kifejezést, amire most $F{KAT} értéket adtuk meg. Egy-egy checkbox segítségével azt is meg kell adnunk, hogy szeretnénk-e a csoport számára header és/vagy footer sávokat létrehozni (mi most mindkettőt kiválasztottuk). A sávok – ahogy a nevük alapján bizonyára kitalálta mindenki – a csoportok előtt és után jelenítődnek meg, általában valami összegző, a csoportra jellemző információval. Szeretnénk kiemelni, hogy a kategoriaGroup COUNT változót a rendszer automatikusan hozta létre, a csoport pillanatnyi elemszámát tartalmazza, így amikor a footerben megjelenítjük, akkor a teljes csoport sorainak számát fogja hordozni. A létrejött 2 sáv a riport tervezőben is megjelent (7.3 ábra), egy- JasperReports Az adatok csoportokba foglalása előre persze

üresen, a későbbiekben mi teszünk a Variable Class is számtípus lesz, esetünkben ki rá tartalmat. BigDecimal. A katGrpTeruletSum változó létrehozása Szeretnénk a csoport footer sávjában megjeleníteni az adott kategóriába tartozó összes országot és azok összterületét. Az 1 értékét a már említett automatikusan létrejött változó tartalmazza, azonban a 2. tartalmi elem értékének gyűjtéséhez hozzunk létre egy katGrpTeruletSum nevű változót, aminek beállításait a 72 ábra mutatja. Itt több újdonságra felhívjuk a figyelmet: 7.2 ábra: A katGrpTeruletSum változó 1. A Reset type értéke most Group lett, azaz egy csoport kezdetekor kell a változót inicializálni. A tartalom befejezése és egy kis formázás 2. A Reset group pedig a mi kategoriaGroup A 7-1 Programlista mutatja a jrxml fájl esetünk csoportunk lett. szempontjából lényeges részeit, ennek design néA Calculation értéke Sum, hiszen most az oszlop zetét mutatja az

iReport 7.3 ábrán látható részértékeinek összege kell nekünk Emiatt persze lete Vegyük sorra a lényeges változtatásokat! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 // 7 −1. P r o g r a m l i s t a : Orszagok−GRP. j r x m l <?xml v e r s i o n ="1.0" e n c o d i n g ="UTF−8"?> <j a s p e r R e p o r t . . <q u e r y S t r i n g l a n g u a g e ="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k o r d e r by k a t ] ] > </ q u e r y S t r i n g > . < f i e l d name="GDP" c l a s s =" j a v a . l a n g I n t e g e r "/> < f i e l d name="KAT" c l a s s =" j a v a . l a n g I n t e g e r "/> . < v a r i a b l e name="katGrpTeruletSum " c l a s s =" j a v a . math B i g D e c i m a l " r e s e t T y p e ="Group " r e s e t G r o u p ="å k a t e g o r i

a G r o u p " c a l c u l a t i o n ="Sum"> <v a r i a b l e E x p r e s s i o n > <![CDATA[ $F{TERULET}]] > </ v a r i a b l e E x p r e s s i o n > </ v a r i a b l e > <g r o u p name=" k a t e g o r i a G r o u p "> <g r o u p E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ g r o u p E x p r e s s i o n > <groupHeader> <band h e i g h t ="34"> <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="1 f d 2 e b 7 a −f d 0 9 −4849−9 f 5 6 −50 a 0 7 8 6 5 7 b e c " mode="Opaque "å x="0" y="0" w i d t h ="555" h e i g h t ="34" b a c k c o l o r="#FF6633"/> </ r e c t a n g l e > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d=" f c 5 f 3 5 4 c −3535−4035− a396 −84619 bc058d3 " x="85" y="10"å w i d t h ="100" h e i g h t

="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="89 aa5dcd −568a−4c24−b2e7−c c 6 c 1 3 e d a 2 7 c " x="5" y="10" å w i d t h ="77" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Új k a t e g ó r i a :]] > </ t e x t > </ s t a t i c T e x t > </band> </groupHeader> 77 JasperReports 39 40 41 42 <g r o u p F o o t e r > <band h e i g h t ="37"> <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="0192 bb82 −605b−42a6−ad30

−0d e 9 0 9 b d 1 b c 8 " x="76" y="7" å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d=" b c 3 9 9 f 7 c −38d0 −4586−8b17−c 1 6 d 1 6 5 4 e 0 5 7 " x ="160" y="7"å w i d t h ="40" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{ kategoriaGroup COUNT }]] > </å textFieldExpression > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t

E l e m e n t u u i d ="2922 ed41−e2d2 −4d63 −8691−7 e 4 8 2 2 6 b 3 5 0 7 " x ="202" y="7"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ o r s z á g ]] > </ t e x t > </ s t a t i c T e x t > < t e x t F i e l d p a t t e r n ="#,##0.00;−#,##000"> <r e p o r t E l e m e n t u u i d ="124 d15ae −9111−43 c6−aad3 −69 e b 4 0 e d f 4 e a " x ="401" y="7"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{ katGrpTeruletSum }]] > </å textFieldExpression > </ t e x t F i e l d

> <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="89 aa5dcd −568a−4c24−b2e7−c c 6 c 1 3 e d a 2 7 c " x="4" y="7" å w i d t h ="57" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ K a t e g ó r i a :]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="91 e e c 8 5 b −5 f 4 f −4c52 −9478− f d 8 d 3 6 4 d c 2 1 8 " x ="321" y="7"å w i d t h ="70" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Ö s s z t e r ü l e t :]] > </ t e x t > </ s t a t i c T e x t > </band> </g r o u p F o o t e r > </group> 43

44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 Az adatok csoportokba foglalása . </ j a s p e r R e p o r t > Az első figyelemre méltó dolog a 7. sorban lévő queryString, ahol az order by résznél a KAT (kategória) szerinti rendezettséget kértük, ugyanis a riport ezen szempont szerint lesz csoportosítva. Amennyiben ez elmarad, úgy a JasperReports csinál csoportokat, de a végeredmény nem lesz helyes, hiszen ő csak annyit néz, hogy a következő rekord kulcsa egyezik-e a jelenlegivel. A 10-11 sorok csak a 2 új mezőt mutatják, az eddigiekben ezek nem voltak használva A 13-15 sorok a már ismert katGrpTeruletSum változót vezetik be. A 16-85 sorok a teljes kategoriaGroup csoportot leírják A 17 sor tar78 talmazza a groupExpression címkét, ahol a csoportképző kifejezésünk most ez: $F{KAT}. A groupHeader sáv a következő tartalomból áll: • Egy téglalap

(narancssárga színnel). • Az „Új kategória:” címke. • Egy textField a $F{KAT} értékkel, azaz mutatjuk, hogy éppen melyik csoportba léptünk be. A 39. sorban kezdődő groupFooter sáv tartalma: • Mutatja, hogy éppen melyik kategóriát zárjuk le. JasperReports Az adatok csoportokba foglalása • Mutatva a csoport számosságát, megjeleníti a $V{kategoriaGroup COUNT} értéket. • Feltünteti a $V{katGrpTeruletSum} értéket is, ami a csoportba tartozó összterület. 7.3 ábra: A riport template 7.4 ábra: A kategóriánként való összegfokozatos lista egy részlete 79 JasperReports Az adatok csoportokba foglalása A 7.3 ábrán látható riportot az iReport Preview fülével is lefuttathatjuk, eredményül a 74 ábrán látható eredményt kapjuk. A formázás egyszerű, de talán már ez is hatásos. A csoportok nyitását a narancssárga, átlátszó téglalap emeli ki, azok zárását pedig csak a vastagon szedett footer sor. Egy új

csoportosítási szempont Az előző riportot kiegészítjük egy új csoporto7.5 ábra: Az orszagnevGroup csoport sítási szemponttal, azaz a kategóriákon belül az országok neveit is csoportba szedjük. A helyes A csoport létrehozása után ismét készítsünk működés érdekében a queryString order by réegy összegző változót (neve: orszGrpTeruletszébe elhelyeztük az orszag oszlopot is: Sum), amit 7.6 ábra ismertet A változó 3 s e l e c t ∗ from o r s z a g o k o r d e r by kat , o r s z a g legfontosabb tulajdonsága a következő: A kezdőbetűk szerinti csoport 1. A Reset type=Group, ami most az orszagnevGroup csoportra van állítva Vegyünk fel egy új orszagnevGroup nevű csoportot, aminek a jellemzőit a 7.5 ábra mutatja A csoportképző kifejezés a következő: 2. Az változó kifejezése $F{TERULET}, hiszen a területet akarjuk összegezni $F{ORSZAG} . s u b s t r i n g ( 0 , 1 ) 3. A Calculation=Sum Ez azt jelenti, hogy a generátor akkor teszi

a következő sort új csoportba, ha az ország kezdőbetűje változik. Itt ragadjuk meg a lehetőséget, hogy a csoportok néhány további jellemzőjét ismertessük: • Band height: a csoport header vagy footer sávjának magassága. • Start on new page: Amennyiben igaz, úgy a csoport renderelése új lapra lesz elkezdve. 7.6 ábra: Az orszGrpTeruletSum változó • Reset page number : Igaz esetén a csoport- A megváltoztatott riport terv váltáskor a lapszámozás is elölről kezdődik. A 7.7 ábra az új jrxml fájl vizuális képét tar• Reprint header : Amennyiben kérjük, úgy talmazza az iReport eszközzel való tervezés köza csoporthoz a fejlécszövegek is kinyomta- ben A kategória csoportot narancssárga, míg az ország kezdőbetű csoportot sárga színnel emeltódnak. tük ki, hogy a jelentés olvasóinak könnyebb le• Footer Position: Hol legyen a csoport foo- gyen eligazodnia a 2 összegfokozat váltás között. ter sáv. Ezt a hatást úgy tudtuk

elérni, hogy kitettünk 80 JasperReports Az adatok csoportokba foglalása néhány téglalap (rectangle) elemet, átlátszó be- konstans szövegeket és a csoportosítást adó meállítással és a megfelelő háttérszínnel. A sárga zőt és annak megnevezését sávokra is felhelyeztük a megfelelő 2 változót, a 7.7 ábra: A riport template 7.8 ábra: Riport eleje 81 JasperReports Az adatok csoportokba foglalása 7.9 ábra: Riport közepe 7.10 ábra: A riport közepe 82 JasperReports Az adatok csoportokba foglalása A 7.8, 79 és 710 ábrák az elkészült jelentés toztatást tettünk a jrxml terven és annak tanulszerkezeti szempontból lényegesebb részeit mu- mányozásából is sokat lehet tanulni, úgy most a tatják be. Tekintettel arra, hogy most sok vál- 7-2 Programlista a teljes fájlt tartalmazza 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52

53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 // 7 −2. P r o g r a m l i s t a : Orszagok−GRP. j r x m l <?xml v e r s i o n ="1.0" e n c o d i n g ="UTF−8"?> <j a s p e r R e p o r t xmlns="h t t p : / / j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " xmlns : x s i ="h t t p : / /www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n="h t t p : / / j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s h t t p : / / å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name="Orszagok−GRP" l a n g u a g e ="g r o o v y " pageWidth ="595" å p a g e H e i g h t ="842" columnWidth ="555" l e f t M a r g i n ="20" r i g h t M a r g i n ="20" t o p M a r g i n ="20" bottomMargin

="20" u u i d å ="9a1dbe76 −1ae5 −4418−9 e43−e 5 6 f 6 e d 9 8 1 9 3 "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e ="10"/ > <p r o p e r t y name=" i r e p o r t . x " v a l u e ="0"/> <p r o p e r t y name=" i r e p o r t . y " v a l u e ="0"/> <q u e r y S t r i n g l a n g u a g e ="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k o r d e r by kat , o r s z a g ] ] > </ q u e r y S t r i n g > < f i e l d name="ORSZAG" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="FOVAROS" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="FOLDR HELY" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="TERULET" c l a s s =" j a v a . math B i g D e c i m a l "/> < f i e l d

name="ALLAMFORMA" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="NEPESSEG" c l a s s =" j a v a . l a n g I n t e g e r "/> < f i e l d name="NEP FOVAROS" c l a s s =" j a v a . l a n g I n t e g e r "/> < f i e l d name="AUTOJEL" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="COUNTRY" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="CAPITAL" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="PENZNEM" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="PENZJEL" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="VALTOPENZ" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="TELEFON" c l a s s =" j a v a . l a n g I n t e g e r

"/> < f i e l d name="GDP" c l a s s =" j a v a . l a n g I n t e g e r "/> < f i e l d name="KAT" c l a s s =" j a v a . l a n g I n t e g e r "/> < v a r i a b l e name="katGrpTeruletSum " c l a s s =" j a v a . math B i g D e c i m a l " r e s e t T y p e ="Group " r e s e t G r o u p ="å k a t e g o r i a G r o u p " c a l c u l a t i o n ="Sum"> <v a r i a b l e E x p r e s s i o n > <![CDATA[ $F{TERULET}]] > </ v a r i a b l e E x p r e s s i o n > </ v a r i a b l e > < v a r i a b l e name="o r s z G r p T e r u l e t S u m " c l a s s =" j a v a . math B i g D e c i m a l " r e s e t T y p e ="Group " r e s e t G r o u p ="å o r s z a g n e v G r o u p " c a l c u l a t i o n ="Sum"> <v a r i a b l e E x p r e s s i o n > <![CDATA[ $F{TERULET}]] > </ v a r i a b l

e E x p r e s s i o n > </ v a r i a b l e > <g r o u p name=" k a t e g o r i a G r o u p "> <g r o u p E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ g r o u p E x p r e s s i o n > <groupHeader> <band h e i g h t ="34"> <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="1 f d 2 e b 7 a −f d 0 9 −4849−9 f 5 6 −50 a 0 7 8 6 5 7 b e c " mode="Opaque "å x="0" y="0" w i d t h ="555" h e i g h t ="34" b a c k c o l o r="#FF3300"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d=" f c 5 f 3 5 4 c −3535−4035− a396 −84619 bc058d3 " x ="121" yå ="10" w i d t h ="100" h e i g h t ="20"/> <t e x t E l e

m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="89 aa5dcd −568a−4c24−b2e7−c c 6 c 1 3 e d a 2 7 c " x="30" y="10"å w i d t h ="77" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Új k a t e g ó r i a :]] > </ t e x t > </ s t a t i c T e x t > </band> </groupHeader> <g r o u p F o o t e r > <band h e i g h t ="34"> <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="966234 e7−d837 −409d−812e−b 9 2 3 a c a e 5 f d d " x="0" y="0" å w i d t h

="555" h e i g h t ="34" b a c k c o l o r="#FF3300"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="0192 bb82 −605b−42a6−ad30 −0d e 9 0 9 b d 1 b c 8 " x="90" y="7" å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > 83 JasperReports 70 71 72 73 74 75 Az adatok csoportokba foglalása <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{KAT}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d=" b c 3 9 9 f 7 c −38d0 −4586−8b17−c 1 6 d 1 6 5 4 e 0 5 7 " x ="169" y="7"å w

i d t h ="40" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{ kategoriaGroup COUNT }]] > </å textFieldExpression > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="2922 ed41−e2d2 −4d63 −8691−7 e 4 8 2 2 6 b 3 5 0 7 " x ="231" y="7"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ o r s z á g ]] > </ t e x t > </ s t a t i c T e x t > < t e x t F i e l d p a t t e r n ="#,##0.00;−#,##000"> <r e p o r t E l e m e n t u u i d ="124 d15ae −9111−43 c6−aad3 −69 e b 4 0 e d f

4 e a " x ="431" y="7"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{ katGrpTeruletSum }]] > </å textFieldExpression > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="89 aa5dcd −568a−4c24−b2e7−c c 6 c 1 3 e d a 2 7 c " x="21" y="7" å w i d t h ="57" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ K a t e g ó r i a :]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="91 e e c 8 5 b −5 f 4 f −4c52 −9478−

f d 8 d 3 6 4 d c 2 1 8 " x ="341" y="7"å w i d t h ="70" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Ö s s z t e r ü l e t :]] > </ t e x t > </ s t a t i c T e x t > 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 </band> </g r o u p F o o t e r > </group> <g r o u p name="o r s z a g n e v G r o u p"> <g r o u p E x p r e s s i o n > <![CDATA[ $F{ORSZAG} . s u b s t r i n g ( 0 , 1 ) ]] > </ g r o u p E x p r e s s i o n > <groupHeader> <band h e i g h t ="34"> <r e c t a n g l e > <r e p o r t E l e m e n t u u i d="b e 6 7 4 5 e 6 −20b7−4564−ba40 −85 a 5 6 2 9 f 4 8 d 5 " x="21"

y="0" å w i d t h ="534" h e i g h t ="34" b a c k c o l o r="#FFFF00"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="3 f d 0 4 a e 0 −4e85 −45 f 6 −b 4 f 4 −f 1 1 6 b 8 c 5 8 6 e 3 " x="41" y="10"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Kezdőbetű :]] > </ t e x t > </ s t a t i c T e x t > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d="a06845a7 −7346−4039−9d04 −3293106101 b7 " x ="141" yå ="10" w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n

t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{ORSZAG} . s u b s t r i n g ( 0 , 1 ) ]] > </å textFieldExpression > </ t e x t F i e l d > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 " x="11" y="0" å w i d t h ="10" h e i g h t ="34" b a c k c o l o r="#FFFF00"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 " x="0" y="0" å w i d t h ="10" h e i g h t ="34" b a c k c o l o r="#FF3300"/> <g r a p h i c E l e m e n t > 118 119 120 121 122

123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 84 JasperReports 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 Az adatok csoportokba foglalása <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > </band> </groupHeader> <g r o u p F o o t e r > <band h e i g h t ="34"> <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="5cd22b40−f 8 a 5 −4f a 2 −bde8−e f c b 1 e f f 0 0 5 0 " x="21" y="0" å w i d t h ="534" h e i g h t ="34" b a c k c o l o r="#FFFF00"/> <g r a p h i c E l e m e n t > <pen l i n

e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="53 f c 1 0 9 c −723b−4c65 −99c7−bd5127db3c57 " x ="169" y="7"å w i d t h ="52" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{orszagnevGroup COUNT}]] > </å textFieldExpression > </ t e x t F i e l d > < t e x t F i e l d p a t t e r n ="#,##0.00;−#,##000"> <r e p o r t E l e m e n t u u i d ="0 f 6 5 e 2 4 6 −c037 −4e86 −853c−6f 7 3 2 9 0 d 1 7 7 a " x ="431" y="8"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t

> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{ o r s z G r p T e r u l e t S u m }]] > </å textFieldExpression > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="7253351b−8151−4 f 0 a −9a 7 f −e 4 6 c f e 2 7 c 8 f 5 " x="29" y="8" å w i d t h ="26" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{ORSZAG} . s u b s t r i n g ( 0 , 1 ) ]] > </å textFieldExpression > </ t e x t F i e l d > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d=" c c 3 1 c c a e −e521 −423a −8234−73 c 6 1 0 3 7 5 3 1 8 " x="55" y="8" å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d

=" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ b e t ű :]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="08 e c 4b 2 4 −2637−4453− a234 −9 a f 0 1 2 f a 0 4 9 e " x ="231" y="8"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ o r s z á g ]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d="a3b0844d −68bb−4b1e −911 f −990 e e a 2 9 a 0 3 c " x ="341" y="7"å w i d t h ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Ö s

s z t e r ü l e t :]] > </ t e x t > </ s t a t i c T e x t > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 " x="0" y="0" å w i d t h ="10" h e i g h t ="34" b a c k c o l o r="#FF3300"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 " x="11" y="0" å w i d t h ="10" h e i g h t ="34" b a c k c o l o r="#FFFF00"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > </band> </g r o u p F o o t e r > </group>

<background> <band s p l i t T y p e =" S t r e t c h "/> </background> <t i t l e > <band h e i g h t ="79" s p l i t T y p e =" S t r e t c h "> <s t a t i c T e x t > 85 JasperReports 221 Az adatok csoportokba foglalása <r e p o r t E l e m e n t u u i d="b4880372−f0bd −40c2 −98d9−9 f 0 f e 4 3 3 d c 2 1 " x="55" y="14" w i d t h å ="405" h e i g h t ="31"/> <t e x t E l e m e n t > <f o n t s i z e ="24"/> </t e x t E l e m e n t > <t e x t > <![CDATA[ Az o r s z á g o k l e g f o n t o s a b b a d a t a i ]] > </ t e x t > </ s t a t i c T e x t > 222 223 224 225 226 227 228 229 230 231 232 </band> </ t i t l e > <pageHeader> <band h e i g h t ="26" s p l i t T y p e =" S t r e t c h "> <s t a t i c T e x t > <r e p o r t E l e m e n t u

u i d="d e b 8 1 f e d −e 3 4 f −4bd0−ae94 −0508 a f 0 9 f f 2 5 " x ="444" y="0" w i d t hå ="100" h e i g h t ="20" f o r e c o l o r ="#FF0066"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ T i t k o s !]] > </ t e x t > </ s t a t i c T e x t > </band> </pageHeader> <columnHeader> <band h e i g h t ="23" s p l i t T y p e =" S t r e t c h "> <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d=" c e 8 a 1 1 b f −2f 1 1 −474c−bb67−6e 8 8 0 2 7 5 2 4 5 8 " x="29" y="2" w i d t h å ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t

> <![CDATA[ O r s z á g ]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="491 c f 4 f 0 −e e a a −4d9e −909a−8e e 4 9 5 1 8 b 2 4 e " x ="131" y="0" w i d t h å ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e " p d f E n c o d i n g="Cp1250 " isPdfEmbedded=" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ F ő v á r o s ]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d=" f f 2 e f e e a −6633−4b8a−8a04 −9328 b 0 a c 5 6 d a " x ="241" y="3" w i d t hå ="100" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t

> <![CDATA[ F ö l d r é s z ]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d ="0 d c a 2 b f f −1bc1 −439d−9913− b76866beb8da " x ="371" y="3" w i d t h å ="81" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t"> <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[ T e r ü l e t ]] > </ t e x t > </ s t a t i c T e x t > <s t a t i c T e x t > <r e p o r t E l e m e n t u u i d=" f 0 4 3 f 1 c 1 −d f 3 7 −4c5a −9f 8 a −977 b 9 a 2 c 8 8 d 5 " x ="477" y="0" w i d t h å ="67" h e i g h t ="20"/> <t e x t E l e m e n t > <f o n t i s B o l d =" t r u e "/> </t e x t E l e m e n t > <t e x t > <![CDATA[GDP]] >

</ t e x t > </ s t a t i c T e x t > </band> </columnHeader> <d e t a i l > <band h e i g h t ="34" s p l i t T y p e =" S t r e t c h "> <t e x t F i e l d > <r e p o r t E l e m e n t u u i d="a2856d02 −9 c e f −48e3 −9240− c f 0 a 1 1 b 7 6 4 8 8 " x="29" y="12" w i d t h å ="100" h e i g h t ="20"/> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{ORSZAG}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="5 e 6 f f 3 5 e −58db−418b−9bcb−e 4 f 4 0 4 4 1 8 5 e 0 " x ="131" y="12" w i d t h å ="100" h e i g h t ="20"/> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{FOVAROS}]] > </ t e x t F i e l d E

x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d="be169129 −86a9 −47c3 −829a −4196 d e c f 2 7 1 c " x ="241" y="12" w i d t h å ="83" h e i g h t ="20"/> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{FOLDR HELY}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d="a583d337 −91a5−4ee 2−b 1 c f −3b c d 4 5 4 2 9 f 8 a " x ="362" y="12" w i d t hå ="90" h e i g h t ="20"/> 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 86 JasperReports 298

299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 Az adatok csoportokba foglalása <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t "/> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{TERULET}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <t e x t F i e l d > <r e p o r t E l e m e n t u u i d="ad96b438−b89c −40 b f −80bd−53 db93 c7a2 ab " x ="477" y="12" w i d t h å ="71" h e i g h t ="20"/> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $F{GDP}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 "

x="0" y="0" w i d t h å ="10" h e i g h t ="34" b a c k c o l o r="#FF3300"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > <r e c t a n g l e > <r e p o r t E l e m e n t u u i d ="114 e71bd −1f b 9 −41e9−b3fd−c 0 d 9 5 1 0 7 c e b 2 " x="11" y="0" w i d t hå ="10" h e i g h t ="34" b a c k c o l o r="#FFFF00"/> <g r a p h i c E l e m e n t > <pen l i n e W i d t h ="0.0"/ > </g r a p h i c E l e m e n t > </ r e c t a n g l e > </band> </ d e t a i l > <c o l u m n F o o t e r > <band h e i g h t ="45" s p l i t T y p e =" S t r e t c h "/> </c o l u m n F o o t e r > <p a g e F o o t e r > <band h e i g h t ="54" s p l i t T y p e =" S t

r e t c h "> <t e x t F i e l d > <r e p o r t E l e m e n t u u i d ="238 f 2 d f b −d246 −46b7−97b1−90 f b d f 7 d 8 6 9 e " x ="241" y="19" w i d t hå ="80" h e i g h t ="20"/> <t e x t E l e m e n t t e x t A l i g n m e n t ="R i g h t "/> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{PAGE NUMBER}+" /"]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d > < t e x t F i e l d e v a l u a t i o n T i m e ="R e p o r t"> <r e p o r t E l e m e n t u u i d ="45046766 −1 c1b −4a3b −8380−9 e c 2 6 8 d 6 f 7 d f " x ="331" y="19" w i d t h å ="40" h e i g h t ="20"/> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n > <![CDATA[ $V{PAGE NUMBER}]] > </ t e x t F i e l d E x p r e s s i o n > </ t e x t F i e l d >

</band> </p a g e F o o t e r > <summary> <band h e i g h t ="42" s p l i t T y p e =" S t r e t c h "/> </summary> </ j a s p e r R e p o r t > A 8-10 sorok a már említett rendezettségű SQL select-et tartalmazzák. A 11-26 sorok annyi mezőt definiálnak, ahány oszlopa van a select parancsnak, noha mi ezekből csak párat használunk. A 27-32 sorok között található a 2 csoportra állított összegző változó Emlékeztetjük az olvasót, hogy van még 2 rejtett változó is, amik automatikusan jöttek létre a csoporttal, annak sorait számlálják. A 33-111 sorok között a külső, míg a 112-214 sorok között a belső csoportosítás teljes leírása látható. Az XML fájl teljes tartalma az iReport eszközzel készült, azt manuálisan elkészíteni elég nagy munka lett volna. Ez a RAD eszköz az, amit minden esetben használnunk kell, hiszen a formára is jól kinéző és gyorsan elkészíthető riport

alapkövetelmény. Ezt megfogadva a következő cikkben az iReport lehetőségeit tekintjük át, azonban megjegyezzük, hogy annak minden részletét nem tudjuk leírni. Célunk egy olyan áttekintés adása, amivel utána mindenki könnyebben használhatja és maga is megtalálhatja a kívánt megoldáshoz vezető utat. Ebben a részben nézzük át a komponens palettát és felfedezzük az eddig használt alapelemeken kívül fellelhető további vizuális komponenseket is. 87 JasperReports 8. Az iReport - A riport külalakjának megtervezése Az iReport - A riport külalakjának megtervezése Ebben a cikkben a jrxml design fájlok elsődleges vizuális szerkesztő programját, az iReport eszközt fogjuk bemutatni. A jrxml template-eket mindenképpen ezzel érdemes elkészíteni, mert ez egy RAD eszköz, ami hatékony fejlesztést biztosít. Az ismerkedés közben további érdekes JasperReports lehetőségeket is bemutatunk. 8.1 ábra: Az iReport varázsló indítása

lépéseken, de előtte kiválaszthatunk egy jelentés kinézet témát is, ha szeretnénk. A riport készíEgy új riport designt legegyszerűbben az iReport tése során van néhány központi ablak, amin kevarázsló (8.1 ábra, File New) segítségével resztül alapvető funkciókat érhetünk el. Ezeket kezdhetünk el elkészíteni. Ez végigvezet bennüna Window főmenüpontból tudjuk kiválasztani és ket az ezek a legfontosabbak (korábban már mindegyik képet láttuk): • adatforrás query, Az iReport főbb részei • a mezők kiválasztása, • és csoportosítás 88 • Report Inspector (7.1 ábra): A feladata az, hogy a jelentés elemein könnyen tudjunk navigálni, miközben átlátjuk a tel- JasperReports Az iReport - A riport külalakjának megtervezése jes riport struktúráját. Amikor kiválasz• Preview : A riport „röptében” való legenetunk egy sort rajta, akkor lehetőségünk rálása és megtekintése. van ugyanazt a property halmazt

szerkeszteni, mint amikor a rajzvásznon tesszük Az egyes jellemzők jelentése általában egyérugyanezt. Ugyanakkor itt a riport nem telmű, ezért most csak azt nézzük meg, amihez vizuális részeit (változók, mezők, stílusok, kis magyarázatot célszerű tenni. .) is elérjük • iReport Palette: Az 1.4 ábra a teljes iReport felülettel együtt mutatja Innen tudjuk azokat a komponenseket elérni, amiket a tervezővászonra tehetünk. Eddig tipikusan a textField és staticText elemeket használtuk, az alapriportokhoz ezen kívül nem nagyon van másra szükség. • iReport Field : A 2.2 ábra az ORSZAG mező jellemzőinek beállítási lehetőségeit jeleníti meg. Ezek legnagyobb része a kinézettel és megjelenéssel foglalkozik • Report Query (2.1 ábra): Tekintettel arra, hogy minden riport mögött egy adatforrás található, azok megadása és kezelése kiemelten fontos. • Report Expression (6.3 ábra): A 6 cikk részletesen foglalkozik a kifejezések

megadási lehetőségeivel. Riportszintű beállítások Amikor a Report Inspector gyökér elemére (azaz a teljes riportra) jobb egérgombbal kattintunk, akkor kiválaszthatjuk a riportszintű jellemzőket (8.2 ábra) Természetesen minden beállítás itt is a jrxml fájlt változtatja, de lévén az iReport 2-útas eszköz, a jrxml-beli változtatások is látszódnak. A 83 ábra egy részlet a felületből, azt mutatja, hogy a munka közben 3 nézet között kapcsolgathatunk: 8.2 ábra: Riportszintű beállítások • Designer : A vizuális tervezés nézete. • XML: A jrxml szintű kódírás nézete (8.4 ábra). 8.3 ábra: 2-útas eszköz 89 JasperReports Az iReport - A riport külalakjának megtervezése • When no data: Az adatforrás nem mindig hoz sorokat, ebben az esetben elmaradhat a riport generálása. Itt több lehetséges értékből választhatunk, hogy ilyenkor mi történjen. • Language: A kifejezéseket az itt megadott nyelven kell megadni (default

érték: Groovy nyelv). Szintén az egész riportra vonatkozó beállítás a Page Format. helyi menü kiválasztására bejövő ablak, amit a 85 ábrán tekinthetünk meg 8.4 ábra: A jrxml XML nézet Nézzük ezeket a jellemzőket! • Columns: A JasperReports képes több oszlopos szedést is megvalósítani, itt ezek száma adható meg. Ide tartozik a Column space, ami 2 oszlop távolságát jelenti. • Filter Expression: Az adatforrás rekordjait tudjuk szűrni az itt megadott logikai feltétellel. 8.5 ábra: Page Format • Title on a new page: A riport title sávját A stílusok használata új oldalra nyomtatja. Az egyes komponensek sok vizuális beállítási le• Summary on a new page: A riport sum- hetőséggel rendelkeznek, ami nagyon rugalmas a riportok külalakjának beállításakor, azonban sok mary sávját új oldalra nyomtatja. vezérlő esetén már kényelmetlen azok egyenkénti • Ignore Pagination: Amennyiben igaz, úgy konfigurálása. Mint más

környezetekben, itt is a az egész riport 1 oldalra kerül. Ennek a stílus fogalmának bevezetése és használata siet html output esetén van meg az igazi ér- segítségünkre. Amikor a Report Inspector Stytelme les csomópontján egy jobb egérklikket csinálunk, 90 JasperReports akkor az Add menüpont segítségével új stílusneveket hozhatunk létre, amiknek konkrét jellemzőit a 8.6 ábra ablaka segítségével állíthatjuk be. A példában éppen egy TitleStyle nevű stílus kialakítását láthatjuk. Az iReport - A riport külalakjának megtervezése A riport háttér és a vízjel Lehetőségünk van, hogy a riport hátterét megadjuk, amit leggyakrabban a következő okokból szoktunk használni: • Látványosabb legyen a jelentés • Egy vízjelet (watermark) szeretnénk megjeleníteni • Valamilyen előre tervezett lap lesz a háttér és ahhoz képes rendezzük el a riport elemeit. Mindezt a inspector Background csomópontjánál lehet elvégezni. A

háttér egy külön sávon fog megjelenni és jellemzően egy kép komponenst (de akár egyszerű textField -et is) teszünk rá, ami a hátteret adja. A kép hozzáadása után a jrxmlben ez az XML részlet keletkezett: <background> <band h e i g h t ="802" s p l i t T y p e =" S t r e t c h "> <image s c a l e I m a g e =" F i l l F r a m e "> <r e p o r t E l e m e n t p o s i t i o n T y p e =" F l o a t " x="0" yå ="0" w i d t h ="555" h e i g h t ="800"/> <i m a g e E x p r e s s i o n > < ! [CDATA[ " / home/ t a n u l a s / imre−h a l v a n y . j p g " ] ] > </ i m a g e E x p r e s s i o n > </image> </band> </background> Van néhány beállítási lehetőség, de mi ezek közül kettőre szeretnénk felhívni a figyelmet: 8.6 ábra: A stílus property lap Mindez a következő XML részletet fogja a jrxml fájlba generálni:

< s t y l e name=" T i t l e S t y l e " f o r e c o l o r ="#FF3333 " b a c k c o l o r å ="#FFFF66" f i l l =" S o l i d " h A l i g n="C e n t e r " v A l i g n="å M i d d l e " f o n t S i z e ="12"/> 1. Print When Expression: Megadható egy logikai kifejezés, ami dinamikusan értékelődik ki és ettől függően lesz vagy nem lesz háttérkép. 2. Image Expression: Amennyiben képet teszünk háttérnek, úgy annak egy fájlban kell lennie, azonban a fájl neve – és ezzel a laponkénti háttérkép – dinamikusan változhat (A példánkban most éppen az imre-halvany.jpg fájlt tettük konstans kifejezésként) A stílusok használata egyszerű, amennyiben egy komponens támogatja, úgy annak van egy style nevű jellemzője, ott kell beállítani a meg- A Preview fülre kattintva elkészül a riport, amifelelő stílusnevet. nek egy részletét mutatja a 8.7 ábra 91 JasperReports Az

iReport - A riport külalakjának megtervezése ablak (8.8 ábra), amivel igen kifinomultan lehet a komponensek lapon belüli és egymáshoz képesti elrendezését gyorsan beállítani. Amikor csinosítjuk jelentésünket, erről az eszközről soha nem szabad megfeledkeznünk. 8.7 ábra: Háttérkép a riporthoz A példában használtuk az image komponens Scale Image jellemzőjét, azt Fill Frame értékre tettük, aminek hatására a kép kitöltötte a hátteret. Természetesen a képet megadott pozícióra és méretben is kitehetjük háttérként. 8.8 ábra: Gyors elrendezési lehetőség A keretek használata A keretek bevezetése tovább javította a JasperReport template tervezési lehetőségeit. A paA formázás leggyakoribb műveletei a követkelettáról egy keretet elhelyezve egy konténert kazőek: punk, ami egy téglalap alakú rész és tetszőle• pozíció megadás, ges számú komponenst tehetünk bele, aminek a stílusa és kezelése a keretre nézve

egységes lesz. • méretezés, Az iReport-ban a keretet egy egységként tudjuk mozgatni, pozicionálni és színezni, noha több • előtér és háttér színek megadása, komponenst tartalmaz. A jrxml fájlban a keret • egymáshoz képest való elhelyezés. a <frame> tag lesz, ez fogadja be a további eleAmikor kijelölünk egy komponenst, akkor a meket (például a textElement komponenst): property sheet-jén mindezt megadhatjuk, ami- <frame> <r e p o r t E l e m e n t x="42" y="23" w i d t h ="337" h e i g h t å ="114"/> nek jelentős része a jrxml reportElement tag att<s t a t i c T e x t > <r e p o r t E l e m e n t x="46" y="31" w i d t h ="173" h e i g h t å ribútumaként fog megjelenni. Ez a címke min="20"/> <t e x t E l e m e n t /> den komponens fontos része. A Window főme<t e x t > <![CDATA[ Az o r s z á g o k e z e k v o l t a k ]] >

</ t e x t å > nüből választható ki a Formatting Tools Window </ s t a t i c T e x t > A riport elemek formázása </frame> 92 JasperReports 9. Az alriportok (subreports) használata Az alriportok (subreports) használata A JasperReports egy hatékony és kellemes lehetősége az alriportok használata. Képzeljük el, hogy egy olyan jelentést kell készítenünk aminek a logikai szerkezete inkább több riport együtteseként adódik. Ekkor a design megfogalmazása sokkal egyszerűbb a subreport mechanizmus használattal, ami egy kiváló absztrakciós szintnek mutatkozik. A subreport (alriport) egy teljes riport egy • Az adatokat egy jelentésen belül különféle másikba ágyazva. A beágyazott riportot emiatt nézetekben kell prezentálnunk. detail vagy child szóval, míg a beágyazó főriportot master vagy parent jelzővel szokták illetni. Bármilyen, már elkészült riport lehet subreport, Az alriport használata a lényeg csak az, hogy

a főriport hívja meg anEbben a pontban bemutatjuk azt a technikát, nak a hatására, hogy a komponens palettáról kihogy egy meglévő riportba (9.1 ábra) hogy helyeztünk a rajzvászonra egy Subreport elemet. ágyazhatunk be egy tetszőleges másikat. A komponens palettáról húzzuk be a Subreport elemet, esetünkbe most a master riport detail sávjára. Nincs megkötés arra, hogy az alriportot melyik sávra tesszük, de most a feladatunk az lesz, hogy minden egyes országhoz alriportként megvalósítva még megjelenítjük a pénznem, államforma, autó jel és telefon információkat is, emiatt a subreport természetes helye ezen a sávon van. Az ábrán a kis riport ikonnal felszerelt szürke téglalap jelképezi a Subreport komponenst. 9.1 ábra: A master/parent riport Mikor használjunk alriportokat? Van néhány szituáció, amikor érdemes meggondolni az alriport használatának lehetőségét, mert segítheti vagy éppen megvalósíthatóvá teszi a feladat

elkészítését: • Amikor Master/Detail adatszerkezetben tárolt adatokat szeretnénk jelentés formájában megjeleníteni. • Amikor egymással kicsi vagy semmilyen kapcsolatban lévő táblák (adatforrások) tartalmát együtt kell megmutatnunk. 9.2 ábra: Subreport varázsló - 1 93 JasperReports Az alriportok (subreports) használata A komponens elhelyezése után automatikusan elindul a Subreport wizard, aminek most nézzük meg együtt mind a 7 lépését! Az induló ablakban (9.2 ábra) eldönthetjük, hogy az alábbi 3 lehetőségből melyiket szeretnénk: 1. Egy új riport létrehozása, ami az alriportunk lesz majd 2. Egy már korábban elkészített jelentés template-et szeretnénk használni subreport-ként vagy 3. A master riportba most kitett Subreport elemhez most még nem akarunk alriportot megadni. 9.4 ábra: Subreport varázsló - 3 Ezután Next és áttérünk a következő képernyőre (9.5 ábra), ahol a select összes oszlopa felkínálódik, azonban

mi csak azt a 4 oszlopot tettük át a jobb oldalra, amit az alriportban szerepeltetni szeretnénk. 9.3 ábra: Subreport varázsló - 2 A Next gomb a következő ablakhoz (9.3 ábra) vezet, ami a már ismerős Layout kiválasztó funkció. Mi a Blank A4 lehetőséget választottuk, majd továbbmentünk a következő panelre (9.4 ábra) Itt adhatjuk meg az alriport adatforrását, ami nekünk még mindig a HSQLDB adatbázisunkra kiadott select. 94 9.5 ábra: Subreport varázsló - 4 JasperReports Az alriportok (subreports) használata meg, amiket egy-egy rectangle komponens segítségével sárgára színeztünk, így kaptuk a 9.10 ábrán látható design kinézetet. 9.6 ábra: Subreport varázsló - 5 9.8 ábra: Subreport varázsló - 7 9.7 ábra: Subreport varázsló - 6 A 9.6 ábra ablaka most nem fontos nekünk, mert nem szeretnénk a child riportunkba semmilyen csoportosítást, bár volna rá lehetőség. Emiatt menjünk a következő, 9.7 ábra ablakára, ahol az

alriportnak egy fájl nevet adhatunk és rendelkezhetünk arról, hogy mely könyvtárba tárolódjon Az utolsó varázsló lépéshez ismét nyomjunk Next gombot (98 ábra), ahol az adatforrás elérhetőségét lehet beállítani. Az ábrán is látszik, hogy mi ugyanazt a Connection-t fogjuk használni, amit a parent riport is használ. A Finish gomb megnyomására végül legenerálódik a subreport induló váza Erre kitettük a generált 4 mezőt, kitöröltük a felesleges sávokat, azaz csak a column header és detail maradt 9.9 ábra: A subreport komponens jellemzői 95 JasperReports 9.10 ábra: Az alriport A következő lépés az lesz, hogy a master riport Subreport komponensének jellemzőit kell beállítanunk, amit a 9.9 ábra ablakán keresztül érhetünk el Itt a Subreport properties rész az, ami kimondottan alriport komponens specifikus beállító cellákat tartalmaz. Nézzük meg őket egyesével: • Subreport Expression: Értéke $P{SUBREPORT DIR} +

"Orszagokirep sub.jasper" • Connection type: 3 értékből lehet választani aszerint, hogy connection-t vagy adatforrást szeretnék használni, de az is lehet, hogy nem szeretnénk adatokat kapni a riporthoz. • Connection Expression: Az érték most $P{REPORT CONNECTION}, azaz a mester riport kapcsolata. • Parameters: Itt adhatjuk meg, hogy milyen néven melyik paramétereket szeretnénk átadni a subreport részére1 2 3 4 5 6 7 8 9 10 11 12 13 1 2 3 4 5 6 7 8 Az alriportok (subreports) használata A fentieket a jrxml fájl is tartalmazza, amiket a 9-1. és 9-2 Programlistákon láthatunk A 91 Programlista az alriport releváns részét mutatja A 3 sor a parOrszag paramétert határozza meg, mert ez az érték majd a főriporttól fog jönni. A szerepe az, hogy a 6 sor select utasításának where feltételét kiegészítse. Ezzel biztosítható, hogy az alriport mindig csak a paraméterül kapott országra fog lefutni. A 9-2 Programlista a főriport lényeges

részeit mutatja. A detail sávnál észrevehetjük a 14-27 sorok között megadott <subreport> tag-et. Erre úgy kell gondolni, mint egy rutinhívásra, de most ez egy alriport meghívása lesz. Az egyetlen paraméter átadása a 16-20 sorok között történik, ez most éppen a $F{ORSZAG} pillanatnyi értéke. Tekintettel arra, hogy a Subreport komponens a detail sávon van, ezért annak meghívására annyi alkalommal fog sor kerülni, ahány sor kerül a főriportba. A 21-23 sorok közötti connectionExpression tartalmazza a hivatkozást a főriport kapcsolatára, amit ily módon tudunk átpasszolni az alriportnak. Végül a subreportExpression (24-26 sorok) tartalmazza a meghívandó alriport lefordított jasper fájljának az elérhetőségét, hiszen erről tudnunk kell, hogy hol van. Itt HTTP URL is megadható. A főriport Preview fülre kattintva a 9.11 ábra mutatja az elkészült jelentésünket, aminek sárga részei a beágyazott alriportot jelentik. // 9 −1. P r

o g r a m l i s t a : Az Orszagok−i r e p s u b jrxm − r é s z l e t . <p a r a m e t e r name=" p a r O r s z a g " c l a s s=" j a v a . l a n g S t r i n g " /> <q u e r y S t r i n g l a n g u a g e="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where o r s z a g =$P{ p a r O r s z a g } ] ] > </ q u e r y S t r i n g> <f i e l d <f i e l d <f i e l d <f i e l d . name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> // 9 −2. P r o g r a m l i s t a : Az Orszagok−i r e p jrxm − r é s z l e t . < s t y l e name=" T i t l e S t y l e " f o r e c o l o r="#FF3333 " b a c k c o l o

r="#FFFF66" f i l l =" S o l i d " h A l i g n=" C e n t e r " v A l i g n=" M i d d l e " å f o n t S i z e=" 12 " /> <p a r a m e t e r name="SUBREPORT DIR" c l a s s=" j a v a . l a n g S t r i n g " i s F o r P r o m p t i n g=" f a l s e "> <d e f a u l t V a l u e E x p r e s s i o n>< ! [CDATA[ " / home/ t a n u l a s / j a s p e r r e p o r t / p e l d a −1/" ] ] ></ d e f a u l t V a l u e E x p r e s s i o n> </ p a r a m e t e r> <q u e r y S t r i n g 96 l a n g u a g e="SQL"> JasperReports 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 Az alriportok (subreports) használata < ! [CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g> . < d e t a i l> . <s u b r e p o r t> <r e p o r t E l e m e n t x=" 11 " y=" 44 " w i d t h=" 533

" h e i g h t=" 39 " /> <s u b r e p o r t P a r a m e t e r name=" p a r O r s z a g "> <s u b r e p o r t P a r a m e t e r E x p r e s s i o n> < ! [CDATA[ $ F{ORSZAG} ] ] > </ s u b r e p o r t P a r a m e t e r E x p r e s s i o n> </ s u b r e p o r t P a r a m e t e r> <c o n n e c t i o n E x p r e s s i o n> < ! [CDATA[ $ P{REPORT CONNECTION} ] ] > </ c o n n e c t i o n E x p r e s s i o n> <s u b r e p o r t E x p r e s s i o n> < ! [CDATA[ $ P{SUBREPORT DIR} + " Orszagok−i r e p s u b . j a s p e r " ] ] > </ s u b r e p o r t E x p r e s s i o n> </ s u b r e p o r t> . </ d e t a i l> . 9.11 ábra: Az elkészült riport 97 JasperReports 10. Grafikonok használata Grafikonok használata Egy korszerű jelentés az adatok szöveges elrendezése, csoportosítása és összegzése mellett grafikonokat is tartalmazhat. A leíró statisztika sokféle

adatábrázolási formát ismer, amiknek jelentős részét a JasperReports is tudja. Ezzel segíteni tudjuk az adatok értelmezését és a közöttük lévő rejtett összefüggések feltárását. Ebben a cikkben ezeket a lehetőségeket tekintjük át A JasperReports képes a riportokba grafikonokat is generálni. Mindezt az ismert JFreeChart library (webhelye: http://wwwjfree org/jfreechart/) segítségével teszi. Előnyös és érdekes lehetőség, hogy a grafikonok testreszabását egészen a JFreeChart csomag közvetlen használatáig visszanyúlva is el lehet végezni, amennyiben implementáljuk a JRChartCustomizer Java interface-t. Ez utóbbi lehetőségre rövidesen példát is mutatunk ablaka jelenik meg. Miután kiválasztottuk a grafikon típusát (például kördiagram), a komponens felkerül tervező felületre és azt tovább konfigurálhatjuk (példa: 10.2 ábra) Kördiagram 10.2 ábra: Kördiagram A kördiagram a statisztikai sokaság egymástól

megkülönböztetendő elemtípusainak a relatív gyakoriságát (eloszlását) képes szemléletesen ábrázolni. A példánk ennek megfelelően legyen az, hogy az egyes országok kategóriabesorolása szerint mutatjuk meg azok gyakoriságának ala10.1 ábra: Az elérhető grafikon típusok kulását. Annyi körcikk lesz, ahány kategória (az orszagok tábla jelenleg 3 kategóriát tartalmaz). Egy új grafikont a palettáról a tervező vá- A körcikkek mérete az adott kategóriába tartozó szonra behúzott Chart komponens segítségével országok számából fog jönni. Ennek megfeletehetünk be a jelentésbe, amikor a 101 ábra lően ehhez ezt az adatforrás SQL select-et fogjuk 98 JasperReports Grafikonok használata használni, azaz az eredménytábla rendezett kell legyen a KAT oszlopra (10-1. Programlista 1113 sorok): s e l e c t ∗ from o r s z a g o k o r d e r by k a t hagytuk meg, ott láthatóak majd a részösszegek. • A detail sávra nincs szükségünk,

azt töröltük. Ennek megfelelően a riportba sem jelennek meg az adatsorok, de a csoport összegek igen. • Definiáltunk egy vDarabByKat nevű változót (31-33 sorok), ami számolja az összes országot, így a summary sávba a diagram mellé kikerül az összes ország száma is. 10.3 ábra: A kördiagram adathalmaza A 10.2 ábra mutatja az elkészített elrendezést, aminek részletei: • A kördiagram a summary sávba került. • Felvettünk egy Kategoria nevű group-ot (35-41 sorok), ugyanis a kategóriákba tartozó országok számát csoportszinten meg is szeretnénk jeleníteni, amit a kördiagramba tett értékkel hasonlítunk majd össze. A csoportnak csak a footer sávját 1 2 3 4 5 6 7 8 9 10 11 12 13 A kördiagramra jobb egérgombbal kattintva elérhető a Chart Data helyi menü, ahonnan a 10.3 ábra beállító ablakához jutunk, amennyiben a Details fület választjuk. A Key expression egy olyan kifejezés, aminek minden egyes eltérő értéke egy-egy

körcikket fog eredményezni a kördiagramon. Ez esetünkben most $F{KAT}, azaz ahogy jönnek a sorok az adatforrásokból, úgy mindig a bennük lévő kategória kód szerint lesz építve a diagram. A Value expression azt adja meg, hogy a különböző körcikkekhez az értékeket milyen kifejezéssel halmozzuk hozzá. Itt most a Kategoria csoporthoz automatikusan létrejött Kategoria COUNT számláló változót adtuk meg. A körcikkekhez tartozó feliratot most nem itt adtuk meg, hanem a 94. sorban látható {2}/{1}/{0} helytartó szimbólumokkal. Azonban megjegyezzük, hogy amennyiben itt adjuk meg, úgy annak nagyobb a prioritása a megjelenítés szempontjából. A kördiagram teljes megadását a 81-98 sorok között tanulmányozhatjuk // 10 −1. P r o g r a m l i s t a : Az Orszagok−Chart jrxm <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r

g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−Chart " l a n g u a g e=" g r o o v y " pageWidth=" 595 "å p a g e H e i g h t=" 842 " columnWidth=" 535 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 " bottomMargin=" 20 " u u i d=å " 5 1 0 3 0 eb1 −4516−48 e2−a63d −04 d952 6ab4 37 "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r

o p e r t y name=" i r e p o r t . y " v a l u e=" 0 " /> <i m p o r t v a l u e=" o r g . c s t e s t ∗ " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k </ q u e r y S t r i n g> o r d e r by k a t ] ] > 99 JasperReports 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d <f i e l d Grafikonok használata name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> name="TERULET" c l a s s=" j a v a . math B i g D e c i m a l " />

name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> name="KAT" c l a s s=" j

a v a . l a n g I n t e g e r " /> < v a r i a b l e name=" vDarabByKat " c l a s s=" j a v a . l a n g I n t e g e r " c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ 1 ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> <g r o u p name=" K a t e g o r i a "> <g r o u p E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ g r o u p E x p r e s s i o n> <g r o u p F o o t e r> <band h e i g h t=" 50 "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" 79 a a 4 ae 2 −75dd−4 f f a −a85d −4953855 c 6 1 5 5 " x=" 24 " y=" 13 "å w i d t h=" 144 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{Kategoria COUNT} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F

i e l d> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" e 1 a 2 9 4 9 1 −1e8b −403e −964b−1 e 6 f 6 9 d 9 0 9 9 e " x=" 189 " y=" 13å " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ band> </ g r o u p F o o t e r> </ g r o u p> 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 <p a g e H e a d e r> <band h e i g h t=" 58 " /> </ p a g e H e a d e r> <columnHeader> <band h e i g h t=" 53 "> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" 51 f 6 7 3 4 d −3ab5 −40 f 3 −85a4 −8658815 a f 2 7 c " x=" 24 " y=" 12 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l

e m e n t /> <t e x t>< ! [CDATA[ORSZAG ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" 6 a f 8 6 c 2 6 −5f 3 7 −4659−a9a6−b 6 2 6 4 3 a f 9 3 a e " x=" 189 " y=" 12 " w i d t h=å " 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[KAT ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ columnHeader> <c o l u m n F o o t e r> <band /> </ c o l u m n F o o t e r> <summary> <band h e i g h t=" 255 "> < t e x t F i e l d> <r e p o r t E l e m e n t u u i d=" e 5 6 5 c b 9 6 −04c6 −460c−8b77−3 a 1 f 0 0 9 6 a 3 f 7 " x=" 24 " y=" 11 " w i d t h="å 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[

$V{ vDarabByKat } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <p i e C h a r t> <c h a r t e v a l u a t i o n T i m e=" R e p o r t " c u s t o m i z e r C l a s s=" o r g . c s t e s t MyPieChartCustomizerå "> <r e p o r t E l e m e n t u u i d=" f a 7 f e e 6 2 −d 2 f 6 −4419−974e −55 f d 2 7 e 0 b c b d " s t r e t c h T y p e="å R e l a t i v e T o B a n d H e i g h t " x=" 186 " y=" 11 " w i d t h=" 347 " h e i g h t=" 236 " /> < c h a r t T i t l e> < t i t l e E x p r e s s i o n>< ! [CDATA[ " Cimke " ] ] ></ t i t l e E x p r e s s i o n> </ c h a r t T i t l e> < c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <p i e D a t a s e t> <k e y E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ k e y E x p r e s s i o n> <v a l u e

E x p r e s s i o n>< ! [CDATA[ $V{Kategoria COUNT} ] ] ></ v a l u e E x p r e s s i o n> </ p i e D a t a s e t> 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 100 JasperReports 94 95 96 97 98 99 100 101 Grafikonok használata <p i e P l o t </ band> </summary> </ j a s p e r R e p o r t> i s C i r c u l a r=" f a l s e " l a b e l F o r m a t=" { 2 } / { 1 } / { 0 } "> <p l o t /> <i t e m L a b e l /> </ p i e P l o t> </ p i e C h a r t> Az iReport-ban álljunk a Preview fülre, azaz készítsük el a jelentést, aminek eredményét a 10.4 ábra mutatja • {2} A körcikknek megfelelő százalék • {1} A halmozott összeg • {0} A körcikk elem kulcsneve Például a kék körcikk az országok 26%-át tartalmazza, ami a 2. kategóriás országokat jelenti és ebből 50 darab van. Van azonban a diagrammal egy kis gond A

százalékok összege 101%, ami érthető, de nem szép. Amennyiben a tizedesjegyeket is feltüntettük volna, úgy ezzel nem lenne gond, de egészre kerekítve pont az lenne a véletlen, ha pont kijött volna a 100%. A következő részben bemutatjuk a %-ok pontosabb kiírási lehetőségét, amihez felhasználjuk az alkalmat a JRChartCustomizer bemutatására is. Kördiagram - testre szabva A JRChartCustomizer interface egy annyira rugalmas lehetőség, hogy a JFreeChart könyvtár teljes tudását elérhetővé teszi. A JasperReports 10.4 ábra: Az elkészült riport persze igyekszik a tervezőfelületre kivezetni a Látható, hogy nincsenek részletező adatok, grafikonok beállítási lehetőségeit, de ez nyilván azonban az egyes csoportokhoz, azaz kategóriák- nem sikerülhet teljes mértékben. Erre jó példa, hoz tartozó ország darabszámok fel vannak tün- hogy a körcikkek % értékének tizedesjegyeit sem állíthatjuk be, de ekkor kisegíthet minket egy tetve, ez a

mostani konkrét esetre így alakult: osztály, ami implementálja ezt az interface-t. • 1. kategória 69 darab ország Az osztályunk neve most MyPieChartCustomizer lesz és így mondjuk meg a jrxml chart tag• 2. kategória 50 darab ország nél, hogy a generátor használja őt: . • 3. kategória 75 darab ország <c h a r t e v a l u a t i o n T i m e=" R e p o r t " c u s t o m i z e r C l a s s=" o r g . c s å . t e s t MyPieChartCustomizer "> Összesen 194 ország van az orszagok táblában, . ezt a summary sáv mutatja. A kördiagram ponA 10-2 Programlista a class megvalósítását tosan ezt az eloszlást mutatja. Az egyes címkék tartalmazza, láthatjuk, hogy egyáltalán nincs jelentése a megadott {2}/{1}/{0} felépítésnek szó bonyolult dolgokról. Egyedül a customize() megfelelően ez: metódus megvalósításáról szól ez a technika, 101 JasperReports aminek az az ötlete, hogy itt az implementációhoz ajándékba kapjuk a

JFreeChart (JFreeChart reprezentáció) és JRChart (JasperReport reprezentáció) konkrét objektumokat. Ezzel elérhetjük a jasperChart objektum által tárolt beállí1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 Grafikonok használata tásokat és manipulálhatjuk a chart objektumot is. Számunkra a 25 sor hordozza a lényeges lépést, ahol beállítjuk, hogy a százalékok 2 tizedesjeggyel legyenek kiírva. // 10 −2. P r o g r a m l i s t a : MyPieChartCustomizer j a v a package o r g . c s t e s t ; import import import import import import net . net . org . org . org . org . s f . j a s p e r r e p o r t s e n g i n e JRChart ; s f . j a s p e r r e p o r t s e n g i n e JRChartCustomizer ; j f r e e . c h a r t JFreeChart ; j f r e e . chart l a b e l s StandardPieSectionLabelGenerator ; j f r e e . chart plot PiePlot ; j f r e e . chart plot Plot ; /∗ ∗ ∗ ∗ @author i n y i r i ∗/ public c l a s s MyPieChartCustomizer

implements JRChartCustomizer { @Override public void c u s t o m i z e ( JFreeChart c h a r t , JRChart j a s p e r C h a r t ) { Plot plot = chart . getPlot () ; i f ( p l o t instanceof P i e P l o t ) { PiePlot piePlot = ( PiePlot ) plot ; ( ( StandardPieSectionLabelGenerator ) p i e P l o t . getLabelGenerator ( ) ) getPercentFormat ( ) å setMaximumFractionDigits ( 2 ) ; } } } Futtassuk le a riportot, az eredményt a 10.5 ábra mutatja. A százalékokat összeadva most kijön a 100% is, ugyanakkor látjuk, hogy itt miért kerekített a generátor mindenhol felfelé. Kördiagram csoportszinten 10.5 ábra: Javított kördiagram 102 Az előző kördiagram a summary sávban jelent meg. A következőekben a kategória csoportokhoz is rendelünk diagramokat azért, hogy egyegy kategórián belül láthassuk azok terület csoportonkénti megoszlását is Az elkészítendő riport továbbra sem tartalmaz részletező sávot (mert most csak a riport szerkezetébe illesztett grafikont

szeretnénk bemutatni), de 2 egymásba ágyazott group-ot igen, ahogy azt a 10.6 ábrán JasperReports Grafikonok használata látható Report inspector részlet is mutatja. 10.6 ábra: 2 group egymásba ágyazva Esetünkben most a területnagyság (neve: TeruletNagysag) csoportot a következő kifejezés fogja meghatározni: területnagyságok eloszlását, így azokat most a kategória csoport footer sávjára tettük, hiszen a kategóriaváltásoknál van értelme megjeleníteni őket (10.7 ábra) A részletező kördiagramok beállítását a 108 ábrán tekinthetjük meg A jelentés végső kinézetét a 109 ábra tartalmazza Látható, hogy a riport eredményének szerkezete megegyezik az előzővel, de az – ahogy terveztük – kategóriánként tartalmaz még egy-egy kördiagramot is. Nézzük meg például a részletező 2 kördiagram körcikkeit: ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 2 0 0 0 0 0 0 ) Ez más szavakkal azt jelenti, hogy ezek a beágyazott

csoportok lesznek, ahol a számok a négyzetkilométert jelentik: • (0 – 2000000) • [2000000 – 4000000) • Láthatjuk, hogy a 2. kategóriában 2 területnagyság intervallum van: 0 (piros) és 1 (kék), azaz 4000000 négyzetkilométernél nincs nagyobb ország ebben a kategóriában. • A 0 érték száma 47 db, míg az 1 érték 3 db, így a már ismert 50 db ország ki is jön. • A piros 94%, a kék pedig 6% az országoknak, ha a 2. kategóriába belül vizsgálódunk • [4000000 – 6000000) • . A kategória group természetesen maradt a régi A továbbiakban még nézzük meg a riport temp($F{KAT}). A kategória csoport kördiagram- late lényegesebb részeit is röviden, amit a 10-3 jai mutatni fogják a belső csoportnak megfelelő Programlista tartalmaz! 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 // 10 −3. P r o g r a m l i s t a : Az Orszagok−Chart jrxm <?xml version=" 1 . 0 " e n c o d i n

g="UTF−8" ?> <j a s p e r R e p o r t . <i m p o r t v a l u e=" o r g . c s t e s t ∗ " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k </ q u e r y S t r i n g> . <f i e l d <f i e l d <f i e l d <f i e l d o r d e r by kat , t e r u l e t ] ]> name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> name="TERULET" c l a s s=" j a v a . math B i g D e c i m a l " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> < v a r i a b l e name=" vDarabByKat " c l a s s=" j a v a . l a n g I n t e g e r " c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n><

! [CDATA[ 1 ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> <g r o u p name=" K a t e g o r i a "> <g r o u p E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ g r o u p E x p r e s s i o n> <g r o u p F o o t e r> <band h e i g h t=" 158 "> < t e x t F i e l d> <r e p o r t E l e m e n t x=" 16 " y=" 13 " w i d t h=" 108 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> 103 JasperReports Grafikonok használata 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 </ band> </ g r o u p F o o t e r> </ g r o u p> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{Kategoria COUNT} ] ] ></å t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> < t e x t

F i e l d> <r e p o r t E l e m e n t x=" 144 " y=" 13 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <p i e C h a r t> <c h a r t> <r e p o r t E l e m e n t x=" 229 " y=" 0 " w i d t h=" 326 " h e i g h t=" 158 " /> < c h a r t T i t l e /> < c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <p i e D a t a s e t> <d a t a s e t r e s e t T y p e=" Group " r e s e t G r o u p=" K a t e g o r i a " /> <k e y E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 2 0 0 0 0 0 0 ) ] ] >å </ k e y E x p r e s s i o n> <v a l u e E x p r e s s i o n>< ! [CDATA[ $V{ TeruletNagysag

COUNT } ] ] ></å v a l u e E x p r e s s i o n> </ p i e D a t a s e t> <p i e P l o t l a b e l F o r m a t=" { 2 } / { 1 } / { 0 } "> <p l o t /> <i t e m L a b e l /> </ p i e P l o t> </ p i e C h a r t> <g r o u p name=" T e r u l e t N a g y s a g "> <g r o u p E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 2 0 0 0 0 0 0 ) ] ] ></ g r o u p E x p r e s s i o n> </ g r o u p> . <summary> <band h e i g h t=" 198 "> < t e x t F i e l d> <r e p o r t E l e m e n t x=" 24 " y=" 11 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{ vDarabByKat } ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> <p i e C h a r t> <c h a r t e v a l u a t i o n T i m e="

R e p o r t " c u s t o m i z e r C l a s s=" o r g . c s t e s t MyPieChartCustomizerå "> <r e p o r t E l e m e n t s t r e t c h T y p e=" R e l a t i v e T o B a n d H e i g h t " x=" 277 " y=" 0 " w i d t h="å 278 " h e i g h t=" 198 " /> < c h a r t T i t l e> < t i t l e E x p r e s s i o n>< ! [CDATA[ " Cimke " ] ] ></ t i t l e E x p r e s s i o n> </ c h a r t T i t l e> < c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <p i e D a t a s e t> <k e y E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ k e y E x p r e s s i o n> <v a l u e E x p r e s s i o n>< ! [CDATA[ $V{Kategoria COUNT} ] ] ></ v a l u e E x p r e s s i o n> </ p i e D a t a s e t> <p i e P l o t i s C i r c u l a r=" t r u e " l a b e l F o r m a t=" { 2 } / { 1 } / { 0 } "> <p l

o t /> <i t e m L a b e l /> </ p i e P l o t> </ p i e C h a r t> </ band> </summary> </ j a s p e r R e p o r t> A 8-10 sorok közötti queryString alakja: s e l e c t ∗ from o r s z a g o k o r d e r by kat , terulet Itt az order by rész után a terület is része lett a rendezettségi feltételnek, hiszen a 2. (beágyazott) csoport képezi a kördiagram kulcsképző szempontját, ami viszont a TERULET mező függvénye. Az új csoportunk az 58-60 sorok között van, szerepe csak annyi, hogy hivatkozni le104 hessen rá, illetve felhasználjuk az automatikusan generált $V{TeruletNagysag COUNT} értéket is, hiszen az adja a körcikkek méretét. Az eredeti – és most már beágyazó – csoport footer sávja azzal egészült ki, hogy itt helyeztük el 37-51 sorok között látható kördiagram tervet (az adatainak beállítását a 10.8 ábra mutatja) A 19-21 sorok közötti vDarabByKat változó most JasperReports Grafikonok

használata éppen nincs használva, de ha az országok darabszáma helyett a területek összegét akarnánk a kördiagramba tenni, akkor ezt használnánk Value expression gyanánt. 10.7 ábra: Terület csoportonkénti diagram - 1 10.9 ábra: Az elkészült jelentés 10.10 ábra: 3D Kördiagram a summary sávban 10.8 ábra: Terület csoportonkénti diagram - 2 A 2D kördiagramból könnyen készíthető 3D diagram, az iReport automatikusan képes ezt a konverziót elvégezni, aminek eredményeképpen a jrxml-be ezek a változtatások történnek a grafikonra: 105 JasperReports Grafikonok használata • <pieChart> helyett <pie3DChart> tag • <piePlot> helyett <pie3DPlot> tag Ekkor a 10.10 ábra mutatja a summary sáv 3D kördiagramját, ahol most csak a kategória értékek lettek a címkék. Oszlopdiagram Az oszlopdiagram is az egyes értékek közötti arányokat mutatja, de ugyanakkor azok abszolút értékét is jól ábrázolja. Általános

esetben több kategóriát is tudunk ábrázolni, így a 10.9 ábra 3 részletező kördiagramját egyetlen oszlopdiagrammal is kiválthatjuk, ahogy az a 10.11 ábráról kitűnik A X tengely mutatja most az egyes 10.11 ábra: Oszlopdiagram ország kategóriákat (1, 2 és 3), az Y pedig a kategórián belüli területnagyság mértékének eloszA 10.11 ábra a summary sávban van, azt a lását darab egységben kifejezve. Amennyiben a kategóriákon belüli számokat összeadjuk, meg- 10-4. Programlista 8-31 sorok közötti része állíkapjuk a már ismert 69, 50, 75 ország számokat totta elő, így érdemes azt röviden áttekinteni 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 // 10 −4. P r o g r a m l i s t a : Az Orszagok−Chart−BAR jrxm <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t . . <summary> <band h e i g h t=" 398 "> <b a r C h a

r t> <c h a r t> <r e p o r t E l e m e n t x=" 99 " y=" 56 " w i d t h=" 422 " h e i g h t=" 319 " /> < c h a r t T i t l e p o s i t i o n="Top"> < t i t l e E x p r e s s i o n>< ! [CDATA[ " O r s z á g o k k a t e g ó r i a j e l l e m z ő i " ] ] ></ t i t l e E x p r e s s i o n> </ c h a r t T i t l e> < c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <c a t e g o r y D a t a s e t> < c a t e g o r y S e r i e s> < s e r i e s E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 2 0 0 0 0 0 0 ) ] ] ></ s e r i e s E x p r e s s i o n> <c a t e g o r y E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ] ></ c a t e g o r y E x p r e s s i o n> <v a l u e E x p r e s s i o n>< ! [CDATA[ $V{ TeruletNagysag COUNT } ] ] ></ v a l u e E x p r e s s i o n>

< l a b e l E x p r e s s i o n>< ! [CDATA[ $V{ TeruletNagysag COUNT } . t o S t r i n g ( ) ] ] ></ l a b e l E x p r e s s i o n> </ c a t e g o r y S e r i e s> </ c a t e g o r y D a t a s e t> <b a r P l o t i s S h o w L a b e l s=" t r u e "> <p l o t /> <i t e m L a b e l /> <c a t e g o r y A x i s L a b e l E x p r e s s i o n>< ! [CDATA[ " K a t e g ó r i á k " ] ] ></ c a t e g o r y A x i s L a b e l E x p r e s s i o n> <v a l u e A x i s L a b e l E x p r e s s i o n>< ! [CDATA[ " Darabszám " ] ] ></ v a l u e A x i s L a b e l E x p r e s s i o n> </ b a r P l o t> </ b a r C h a r t> </ band> </summary> . </ j a s p e r R e p o r t> 106 JasperReports A 12. sorban látható a grafikon címének beállítása A 28 és 29 sorok pedig az X és Y tengelyek megnevezését adja meg. A leglényegesebb részt 19-22 sorok

között találjuk, itt – oszlopdiagram esetén – 4 különböző dolgot kell megadnunk: • 19. sor: Itt a már ismert terület osztály meghatározó kifejezést találjuk. Ez ad egy adatsorozatot egy-egy oszlopdiagram kategórián belül. • 20. sor: Az X tengelyen megjelenő kategóriákat adó kifejezés, esetünkben most az országok kategória besorolása az. Grafikonok használata Oszlopdiagram - csak 1 kategória Néha nem akarunk különböző kategóriákat az X tengelyre, mert csak a teljes sokaság eloszlását szeretnénk oszlopdiagram formájában ábrázolni. Ilyenkor egyszerű a megoldás, a categoryExpression tag-hez egy konstanst írunk. A 1012 ábra kördiagramja ország kategóriától függetlenül, azaz az összes ország terület besorolása szerinti darabszám eloszlást mutatja. Most a diagramot is tartalmazó teljes jrxml tartalmat bemutatjuk a 10-5 Programlista segítségével • 21. sor: A kategóriánként újraszámító TeruletNagysag COUNT

változó értéke, ami az egyes oszlopok magasságát (esetünkben darabszám) jelenti. A TeruletNagysag group értékváltozásánál történik a reset-je. • 22. sor: A 21 sor értékeit meg is jelenítjük a grafikonon, ez most az oszlop felett megjelenő szám. Szeretnénk 2 megjegyzést tenni: 1. Bármelyik oszlopdiagram 1 attribútummal vertikálisról horizontálissá változtatható 2. A 2D helyett itt is kérhetjük 3D megjelenést 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 10.12 ábra: Oszlopdiagram - 1 kategória // 10 −5. P r o g r a m l i s t a : Az Orszagok−Chart−BAR jrxm <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r

r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−Chart " l a n g u a g e=" g r o o v y " pageWidth=" 595 "å p a g e H e i g h t=" 842 " columnWidth=" 535 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 " bottomMargin=" 20 " u u i d=å " 5 1 0 3 0 eb1 −4516−48 e2−a63d −04 d952 6ab4 37 "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y " v a l u e=" 0 " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k o r d e r by t e r u l e t ] ] > </ q u e r y

S t r i n g> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math B i g D e c i m a l " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> 107 JasperReports 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 Grafikonok használata < f i e

l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> < v a r i a b l e name=" vDarabByKat " c l a s s=" j a v a . l a n g I n t e g e r

" c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ 1 ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> < v a r i a b l e name=" vTerCounter " c l a s s=" j a v a . l a n g I n t e g e r " r e s e t T y p e=" Group " r e s e t G r o u p=" T e r u l e t N a g y s a g " å c a l c u l a t i o n=" Count "> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ $ F{TERULET} ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> <g r o u p name=" T e r u l e t N a g y s a g "> <g r o u p E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 8 0 0 0 0 0 ) ] ] ></ g r o u p E x p r e s s i o n> </ g r o u p> <p a g e H e a d e r> <band h e i g h t=" 58 " /> </ p a g e H e a d e r> <columnHeader> <band h e i g h t=" 53

"> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 16 " y=" 12 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[ORSZAG ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 144 " y=" 12 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[KAT ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ columnHeader> <c o l u m n F o o t e r> <band /> </ c o l u m n F o o t e r> <summary> <band h e i g h t=" 398 "> <b a r C h a r t> <c h a r t> <r e p o r t E l e m e n t x=" 99 " y=" 56 " w i d t h=" 422 " h e i g h t=" 319 " /> < c h a r t T i t l e p o s i t i o n="Top"> < t i t l

e E x p r e s s i o n>< ! [CDATA[ " O r s z á g o k j e l l e m z ő i " ] ] ></ t i t l e E x p r e s s i o n> </ c h a r t T i t l e> < c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <c a t e g o r y D a t a s e t> < c a t e g o r y S e r i e s> < s e r i e s E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 8 0 0 0 0 0 ) ] ] ></ s e r i e s E x p r e s s i o n> <c a t e g o r y E x p r e s s i o n>< ! [CDATA[ " Ö s s z e s " ] ] ></ c a t e g o r y E x p r e s s i o n> <v a l u e E x p r e s s i o n>< ! [CDATA[ $V{ vTerCounter } ] ] ></ v a l u e E x p r e s s i o n> </ c a t e g o r y S e r i e s> </ c a t e g o r y D a t a s e t> <b a r P l o t i s S h o w L a b e l s=" t r u e "> <p l o t /> <i t e m L a b e l /> <c a t e g o r y A x i s L a b e l E x p r e s s

i o n>< ! [CDATA[ " K a t e g ó r i á k " ] ] ></ c a t e g o r y A x i s L a b e l E x p r e s s i o n> <v a l u e A x i s L a b e l E x p r e s s i o n>< ! [CDATA[ " Darabszám " ] ] ></ v a l u e A x i s L a b e l E x p r e s s i o n> </ b a r P l o t> </ b a r C h a r t> </ band> </summary> </ j a s p e r R e p o r t> A 10. sor queryString tag-je, mutatja, hogy a select most természetesen csak a TERULET szerint rendezett, hiszen a KAT most nem játszik szerepet. Lényeges elem a 34-36 sorok közötti TeruletNagysag group, aminek érték ugrásait most 800000-re csökkentettünk, hogy finomabb eloszlást láthassunk a diagramon A diagram most is a summary sávban van, konfi108 gurálását az 59-81 sorok között láthatjuk. Kiemelendő változás, hogy most az oszlop magasságát $V{vTerCounter} kifejezés adja, aminek a változóját a 31-33 sorok között definiáltuk és a számlálás

működését a TeruletNagysag csoporttal szinkronizáltuk. JasperReports Grafikonok használata Itt ismét a teljes jrxml fájlt közöltük, így remélhetőleg könnyebb lesz a teljes riport működéséUtolsó példaként nézzünk meg a X-Y vonaldinek az áttekintése is. Az adatsorokat szolgáltató agram használatát, amit a 10-6. Programlista SQL select 8-10 sorok között tanulmányozható. mutat. A riport futási eredményének diagram részét pedig a 10.13 ábráról tekinthetjük meg X-Y Vonaldiagram 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 // 10 −6. P r o g r a m l i s t a : Az Orszagok−Chart−XYLine jrxm <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a

s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−Chart " l a n g u a g e=" g r o o v y " pageWidth=" 595 "å p a g e H e i g h t=" 842 " columnWidth=" 535 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 " bottomMargin=" 20 " u u i d=å " 5 1 0 3 0 eb1 −4516−48 e2−a63d −04 d952 6ab4 37 "> <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r o p e r t y

name=" i r e p o r t . y " v a l u e=" 0 " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where t e r u l e t < 8 0 0 0 0 0 and t e r u l e t > 5 0 0 0 0 0 o r d e r by t e r u l e t ] ] > </ q u e r y S t r i n g> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math B i g D e c i m a l " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g

e r " /> < f i e l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> < v a r i a b l e name=" vDarabByKat " c l a s s=" j a v

a . l a n g I n t e g e r " c a l c u l a t i o n="Sum"> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ 1 ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> < v a r i a b l e name=" vTerCounter " c l a s s=" j a v a . l a n g I n t e g e r " r e s e t T y p e=" Group " r e s e t G r o u p=" T e r u l e t N a g y s a g " å c a l c u l a t i o n=" Count "> <v a r i a b l e E x p r e s s i o n>< ! [CDATA[ $ F{TERULET} ] ] ></ v a r i a b l e E x p r e s s i o n> </ v a r i a b l e> <g r o u p name=" T e r u l e t N a g y s a g "> <g r o u p E x p r e s s i o n>< ! [CDATA[ ( i n t ) ( $F{TERULET} . i n t V a l u e ( ) / 8 0 0 0 0 0 ) ] ] ></ g r o u p E x p r e s s i o n> </ g r o u p> <p a g e H e a d e r> <band h e i g h t=" 58 " /> </ p a g e H e a d e r> <columnHeader>

<band h e i g h t=" 53 "> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 16 " y=" 12 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[ORSZAG ] ] ></ t e x t> </ s t a t i c T e x t> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 144 " y=" 12 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[KAT ] ] ></ t e x t> </ s t a t i c T e x t> </ band> </ columnHeader> <c o l u m n F o o t e r> <band /> </ c o l u m n F o o t e r> <summary> <band h e i g h t=" 398 "> <x y L i n e C h a r t> <c h a r t> <r e p o r t E l e m e n t x=" 16 " y=" 45 " w i d t h=" 539 " h e i g h t=" 299 " /> < c h a r t T i t l e /> <

c h a r t S u b t i t l e /> <c h a r t L e g e n d /> </ c h a r t> <x y D a t a s e t> <x y S e r i e s> < s e r i e s E x p r e s s i o n>< ! [CDATA[ " 5 0 0 0 0 0 − 8 0 0 0 0 0 km2 k ö z ö t t " ] ] ></ s e r i e s E x p r e s s i o n> <x V a l u e E x p r e s s i o n>< ! [CDATA[ $ F{TERULET} ] ] ></ x V a l u e E x p r e s s i o n> <y V a l u e E x p r e s s i o n>< ! [CDATA[ $ F{NEPESSEG} ] ] ></ y V a l u e E x p r e s s i o n> </ x y S e r i e s> 109 JasperReports 71 72 73 74 75 76 77 78 79 80 Grafikonok használata </ x y D a t a s e t> < l i n e P l o t i s S h o w L i n e s=" t r u e " i s S h o w S h a p e s=" t r u e "> <p l o t /> <c a t e g o r y A x i s L a b e l E x p r e s s i o n>< ! [CDATA[ " T e r ü l e t " ] ] ></ c a t e g o r y A x i s L a b e l E x p r e s s i o n> <v a l u e A x i s L

a b e l E x p r e s s i o n>< ! [CDATA[ " N é p e s s é g " ] ] ></ v a l u e A x i s L a b e l E x p r e s s i o n> </ l i n e P l o t> </ x y L i n e C h a r t> </ band> </summary> </ j a s p e r R e p o r t> 10.13 ábra: X-Y Vonaldiagram Az 56. sortól kezdődő summary sávra tettük a diagramot, aminek a leírása az 58-77 sorok között található és viszonylag egyből megérthető Mindig 2 összetartozó számsorozatot kell előállítani, amiket az xValueExpression és yValueExpression tag-ek között adhatunk meg (68, 69. sorok) Ennek a nevét a seriesExpression tartalmazza, amint látható ez a legend résznél is megjelenik. Az X és Y tengelyek címkéit pedig a 74-75 sorokban látható módon lehetett megadni. 110 További diagramok A JFreeChart könyvtár sok diagram típust ismer, ezek nagy része közvetlenül is elérhető, de testreszabással be is építhető a JasperReportsba: Stacked Bar Chart, Area

Chart, Scatter Plot Chart, Bubble Chart, Time Series Chart, Candlestick Chart. Tervezzük, hogy a szaklap további számaiban ezen diagram fajtákat is bemutatjuk. JasperReports 11. Táblázatos riportok készítése Táblázatos riportok készítése (Crosstab) A JasperReport az 1.1 verzió óta képes olyan kimutatásokat készíteni, amelyek egy táblázatnak felelnek meg. Ez sorokból és oszlopokból áll és ezek találkozásánál olyan cellák vannak, ahova a jellemzők darabszámát, összegét, átlagát, stb. tudjuk generálni Ebben a cikkben bemutatjuk azt is, hogy egy riport alkalmazást milyen módon készíthetünk el webalkalmazásként (servletként). névvel azonosítható további adatforrást is létrehozhatunk, amit a subDataset tag segítségével Néha egy jelentés fontos része, hogy tartalmaztehetünk meg, ahogy a következő példa is muzon egy vagy több táblázatot, amit a JasperRetatja: ports Crosstab komponense segítségével tudunk <s u b D

a t a s e t name="MyDataset"> y S t r i n g l a n g u a g e ="SQL"> könnyen megvalósítani. A komponens palettáról <q u<e! r[CDATA[ s e l e c t ∗ from o r s z a g o k ] ] > </ q u e r y S t r i n g > behúzhatjuk bármelyik sávra a riport igényelt < f i e l d name="ORSZAG" c l a s s =" j a v a . l a n g S t r i n g "/> szerkezetétől függően. Így csoportonként több </s u b D<aftiaesledt >name="FOVAROS" c l a s s =" j a v a l a n g S t r i n g "/> táblázat is megjeleníthető. A 111 ábra mutatja Itt a dataset neve MyDataset és ugyanúgy a komponens behúzása után automatikusan eladható meg, mint az eddig használt fő dataset. induló crosstab varázsló 2. ablakát A crosstab varázsló az 1. ablakban azt kérdezi meg, hogy melyik adatforrást szeretnénk használni. Természetesen a main dataset mindig rendelkezésre áll, de innentől kezdve a MyDataset is

használható. A varázsló 2 képernyője azt is mutatja, hogy a táblázat sorainak kialakításánál több dimenziót is megadhatunk, ahogy az a valódi statisztikai tábláknál gyakorta előfordul. A 3. képernyőn megadható oszlop jellemzők hasonlóan többdimenziósak A 4 képernyőn azt a gyűjtött adatforrásra épülő kifejezést kell megadnunk, aminek számszerű és aggregált értékei kerülnek az egyes cellákba. Érdemes meggondolni, hogy az is egy hatékony lehetőség, hogy az egyes táblákat alriportként szúrjuk be a főriportba, bár erre ritkán van valóban szükség, ugyanis a subDataset segítségével hatékonyan 11.1 ábra: Crosstab varázsló lehet az egyedi, a riport főszerkezetétől eltérő adatforrásokat megfogalmazni. Ennek erejét Amikor egy új táblázatot akarunk beszúrni, mutatja, hogy még paramétereket is átadhaakkor használhatjuk a fő dataset-et, ami az eddig tunk. A MyDataset2 mögött lévő lekérdezés ismert queryString és

adatforrás. Már a diagra- dinamikusan csak azokat az országokat fogja moknál is említtethettük volna, de rugalmassága legyűjteni, ahol az átadott méretnél kisebb az miatt itt mindenképpen szeretnénk kiemelni, ország: hogy egy jrxml fájlban tetszőleges számú, egyedi A táblázat komponens 111 JasperReports Táblázatos riportok készítése <s u b D a t a s e t name="MyDataset2"> <p a r a m e t e r name=" p a r S i z e " c l a s s =" j a v a . l a n g Number"/> <q u e r y S t r i n g l a n g u a g e ="SQL"> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where t e r u l e t < $På { p a r S i z e }]] > </ q u e r y S t r i n g > < f i e l d name="ORSZAG" c l a s s =" j a v a . l a n g S t r i n g "/> < f i e l d name="FOVAROS" c l a s s =" j a v a . l a n g S t r i n g "/> </s u b D a t a s e t > Táblázat az országokról A

használat könnyebb megértése érdekében készítsünk egy olyan táblázatot, ahol a sorok a földrajzi területek, míg az oszlopok az ország kategória szerint vannak csoportosítva. A kimutatásban az érdekel bennünket, hogy az egyes földrajzi helyekbe az egyes kategóriákból hány ország esik, ezért az aggregálás típusa count, azaz leszámlálás lesz. Itt – lévén statisztikáról van szó – sok minden hasonlít a diagramoknál 11.2 ábra: Táblázat - Földrajzi hely/Kategória írtakhoz, de most nem egy grafikon lesz az eredmény, hanem egy táblázat. A táblázat csak azokat az országokat vonja be a vizsgálatba, ahol a A 11-1. Programlista a teljes, létrehozott terulet > 2000000 km2 . A Crosstab komponenst most a summary sávba húzzuk be, az eredményt jrxml fájlt mutatja. A varázsló által generált crosstab részt a 32-142 sorok között láthatjuk. a 11.2 ábra mutatja 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28

29 30 31 32 33 34 35 // 11 −1. P r o g r a m l i s t a : Az Orszagok−Chart−C r o s s t a b jrxm <?xml version=" 1 . 0 " e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−Chart−C r o s s t a b " l a n g u a g e=" g r o o v y " å pageWidth=" 595 " p a g e H e i g h t=" 842 " columnWidth=" 535 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 " å

bottomMargin=" 20 " > <p r o p e r t y name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y " v a l u e=" 0 " /> < s t y l e name=" C r o s s t a b ␣ Data ␣ Text " h A l i g n=" C e n t e r " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where t e r u l e t > 2 0 0 0 0 0 0 o r d e r by FOLDR HELY, KAT ] ] > </ q u e r y S t r i n g> < f i e l d name="ORSZAG" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOVAROS" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="FOLDR HELY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TERULET" c l a s s=" j a v a . math B i g D e c

i m a l " /> < f i e l d name="ALLAMFORMA" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="NEPESSEG" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="NEP FOVAROS" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="AUTOJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="COUNTRY" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="CAPITAL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZNEM" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="PENZJEL" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="VALTOPENZ" c l a s s=" j a v a . l a n g S t r i n g " /> < f i e l d name="TELEFON" c l a s s="

j a v a . l a n g I n t e g e r " /> < f i e l d name="GDP" c l a s s=" j a v a . l a n g I n t e g e r " /> < f i e l d name="KAT" c l a s s=" j a v a . l a n g I n t e g e r " /> <summary> <band h e i g h t=" 398 "> <c r o s s t a b> <r e p o r t E l e m e n t x=" 16 " y=" 17 " w i d t h=" 481 " h e i g h t=" 347 " /> <rowGroup name="FOLDR HELY" w i d t h=" 70 " t o t a l P o s i t i o n="End"> <b u c k e t c l a s s=" j a v a . l a n g S t r i n g "> <b u c k e t E x p r e s s i o n>< ! [CDATA[ $ F{FOLDR HELY} ] ] ></ b u c k e t E x p r e s s i o n> 112 JasperReports 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103

104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 Táblázatos riportok készítése </ b u c k e t> <c r o s s t a b R o w H e a d e r> < c e l l C o n t e n t s b a c k c o l o r="#F0F8FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0 " y=" 0 " w i d t h=" 70 " h e i g h t=" 25 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{FOLDR HELY} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b R o w H e a d e r> <c r o s s t a b T o t a l R o w H e a d e r> < c e l l C o n t e n t s

b a c k c o l o r="#BFE1FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 0 " y=" 0 " w i d t h=" 70 " h e i g h t=" 25 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" C e n t e r " v e r t i c a l A l i g n m e n t=" M i d d l e " /> <t e x t>< ! [CDATA[ T o t a l FOLDR HELY ] ] ></ t e x t> </ s t a t i c T e x t> </ c e l l C o n t e n t s> </ c r o s s t a b T o t a l R o w H e a d e r> </ rowGroup> <columnGroup name="KAT" h e i g h t=" 30 " t o t a l P o s i t i o n="End"> <b u c k e t c l a s s=" j a v a . l a n g I n t e g e r "> <b u c k e t E x p r e s s i o n>< ! [CDATA[ $ F{KAT} ] ]

></ b u c k e t E x p r e s s i o n> </ b u c k e t> <c r o s s t a b C o l u m n H e a d e r> < c e l l C o n t e n t s b a c k c o l o r="#F0F8FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0 " y=" 0 " w i d t h=" 50 " h e i g h t=" 30 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{KAT} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b C o l u m n H e a d e r> <c r o s s t a b T o t a l C o l u m n H e a d e r> < c e l l C o n t e n t s b a c k c o l o r="#BFE1FF" mode=" Opaque

"> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> <s t a t i c T e x t> <r e p o r t E l e m e n t x=" 0 " y=" 0 " w i d t h=" 50 " h e i g h t=" 30 " /> <t e x t E l e m e n t t e x t A l i g n m e n t=" C e n t e r " v e r t i c a l A l i g n m e n t=" M i d d l e " /> <t e x t>< ! [CDATA[ T o t a l KAT ] ] ></ t e x t> </ s t a t i c T e x t> </ c e l l C o n t e n t s> </ c r o s s t a b T o t a l C o l u m n H e a d e r> </ columnGroup> <measure name="GDPMeasure" c l a s s=" j a v a . l a n g I n t e g e r " c a l c u l a t i o n=" Count "> <m e a s u r e E x p r e s s i o n>< ! [CDATA[ $ F{GDP} ] ] ></ m e a s u r e E x p r e s s i o n> </ measure> < c r o s s t a b C e l l w i d

t h=" 50 " h e i g h t=" 25 "> <c e l l C o n t e n t s> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0 " y=" 0 " w i d t h=" 50 " h e i g h t=" 25 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{GDPMeasure} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b C e l l> < c r o s s t a b C e l l h e i g h t=" 25 " rowTotalGroup="FOLDR HELY"> <c e l l C o n t e n t s b a c k c o l o r="#BFE1FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o

l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0 " y=" 0 " w i d t h=" 50 " h e i g h t=" 25 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{GDPMeasure} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b C e l l> < c r o s s t a b C e l l w i d t h=" 50 " columnTotalGroup="KAT"> <c e l l C o n t e n t s b a c k c o l o r="#BFE1FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> 113 JasperReports 124 125 126 127 128 129 130 131 132 133 134 135 136 137

138 139 140 141 142 143 144 145 Táblázatos riportok készítése <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0 " y=" 0 " w i d t h=" 50 " h e i g h t=" 25 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{GDPMeasure} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b C e l l> < c r o s s t a b C e l l rowTotalGroup="FOLDR HELY" columnTotalGroup="KAT"> <c e l l C o n t e n t s b a c k c o l o r="#BFE1FF" mode=" Opaque "> <box> <pen l i n e W i d t h=" 0 . 5 " l i n e S t y l e=" S o l i d " l i n e C o l o r=" #000000 " /> </ box> < t e x t F i e l d> <r e p o r t E l e m e n t s t y l e=" C r o s s t a b ␣ Data ␣ Text " x=" 0

" y=" 0 " w i d t h=" 50 " h e i g h t=" 25 " /> <t e x t E l e m e n t /> <t e x t F i e l d E x p r e s s i o n>< ! [CDATA[ $V{GDPMeasure} ] ] ></ t e x t F i e l d E x p r e s s i o n> </ t e x t F i e l d> </ c e l l C o n t e n t s> </ c r o s s t a b C e l l> </ c r o s s t a b> </ band> </summary> </ j a s p e r R e p o r t> Jó sok sor generálódott, de mindez csak pár Riportkészítő webalkalmazás kattintás volt a Crosstab varázsló használatakor, Befejezésül egy érdekes riporthívási lehetőséget ahol ezeket a jellemzőket adtuk meg: szeretnénk bemutatni, amihez példaképpen a fenti riportot fogjuk használni. A mai világ• FOLDR HELY: A sorok csoportosítási ban fontos az egyes funkciók böngészős elérése, szempontja. így ezt mutatjuk be a következőkben. Szeretnénk kiemelni, hogy a bemutatott megoldás • KAT: Az oszlopok csoportosítási szem-

hosszú futású idejű riportoknál nem ajánlott, mert a HTTP request-response mechanizmusra pontja. épül, ami a beállított time-out érték után meg• GDP: Lehetett volna bármelyik másik osz- szakad, így a riportunkhoz sem fogunk tudni lop is, mert itt csak az előfordulás számát hozzáférni. Ilyenkor is lehet Servlet-et használni, számoljuk (és GDP-je mindenkinek van). de ekkor az külön futási szálon (Thread-en) indítsa el a riport elkészítését A 11-2 Programlista a feladat megoldását adó Java servlet, amit A 11.3 ábra a Report Inspector Crosstab részle- Tomcat, JBoss és Weblogic környezetben is kitét mutatja, ott jól áttekinthető a generált szer- próbáltunk, hibátlanul működik A teszteléshez kezet. az alábbi szerverek futottak a fejlesztői gépen: • Java Webserver (Tomcat vagy JBoss vagy Weblogic) • HSQLDB adatbázis-kezelő (ami tartalmazza az Orszagok táblát is) 11.3 ábra: Crosstab - Report Inspector 114 Érdemes röviden

átnézni a Servlet működését, lehet, hogy nem mindenki ismerős ebben a világban. A lényeg a 32-69 sorok között megvalósított processRequest() metóduson van, azt hívja meg a HTTP kérésre a Webserver is. A kód vázlatát Netbeans környezetben generáltuk, de az ismert JasperReports Eclipse-ben is hasonló lett volna. A request és response metódus paraméterek a kérést és a választ reprezentáló objektumok. A 37 sorban lekérünk egy olyan OutputStream-et (byte folyam, ami visszamegy a böngészőnek), amibe a generált PDF byte-jait tesszük majd. A 38-39 sorokban a riport template-hez (azaz a jasper fájl) jutunk hozzá, amit a reportStream változóba töltünk Ehhez persze az kellett, hogy a web al1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 Táblázatos riportok készítése kalmazáshoz csomagoljuk hozzá a jasper fájlt is. A 43-44 sorokban a HSQLDB adatbázishoz

kapcsolódunk. A 45 sorban legeneráljuk a riportot Használhattuk volna az eddigi módszereinket is, de a JasperReports tartalmaz néhány utility metódust , ilyen a runReportToPdfStream() is. A 46. sorban beállítjuk, hogy a visszaadott tartalom (content) PDF MIME típusú // 11 −2. P r o g r a m l i s t a : J a s p e r S e r v l e t j a v a package o r g . c s t e s t ; import import import import import import import import import import import import import import import import j a v a . i o IOException ; j a v a . i o InputStream ; java . io PrintWriter ; java . io StringWriter ; java . s q l Connection ; j a v a . s q l DriverManager ; j a v a . s q l SQLException ; j a v a . u t i l HashMap ; java . u t i l logging Level ; j a v a . u t i l l o g g i n g Logger ; javax . s e r v l e t ServletContext ; javax . s e r v l e t ServletException ; javax . s e r v l e t ServletOutputStream ; javax . s e r v l e t http HttpServlet ; javax . s e r v l e t http

HttpServletRequest ; javax . s e r v l e t http HttpServletResponse ; import n e t . s f j a s p e r r e p o r t s e n g i n e JRException ; import n e t . s f j a s p e r r e p o r t s e n g i n e JasperRunManager ; /∗ ∗ ∗ ∗ @author i n y i r i ∗/ public c l a s s J a s p e r S e r v l e t extends H t t p S e r v l e t { protected void p r o c e s s R e q u e s t ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) throws S e r v l e t E x c e p t i o n , IOException { C o n n e c t i o n conn = n u l l ; S e r v l e t O u t p u t S t r e a m s e r v l e t O u t p u t S t r e a m = r e s p o n s e . getOutputStream ( ) ; ServletContext ctxServlet = getServletConfig () . getServletContext () ; InputStream r e p o r t S t r e a m = c t x S e r v l e t . g e t R e s o u r c e A s S t r e a m ( " / r e p o r t s / Orszagok−Chart−å Crosstab . j a s p e r " ) ; try { C l a s s . forName ( " o r

g h s q l d b j d b c D r i v e r " ) ; conn = DriverManager . g e t C o n n e c t i o n ( " j d b c : h s q l d b : h s q l : / / l o c a l h o s t /xdb" , "SA" , " " ) ; JasperRunManager . runReportToPdfStream ( r e p o r t S t r e a m , s e r v l e t O u t p u t S t r e a m , new HashMapå ( ) , conn ) ; r e s p o n s e . setContentType ( " a p p l i c a t i o n / p d f " ) ; servletOutputStream . f l u s h () ; servletOutputStream . c l o s e () ; 115 JasperReports 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 } Táblázatos riportok készítése } catch ( E x c e p t i o n e ) { // d i s p l a y s t a c k t r a c e i n t h e b r o w s e r S t r i n g W r i t e r s t r i n g W r i t e r = new S t r i n g W r i t e r ( ) ; P r i n t W r i t e r p r i n t W r i t e r = new P r i n t W r i t e r ( s t r i n g W r i t e r ) ; e . printStackTrace (

printWriter ) ; r e s p o n s e . setContentType ( " t e x t / p l a i n " ) ; r e s p o n s e . getOutputStream ( ) p r i n t ( s t r i n g W r i t e r t o S t r i n g ( ) ) ; } finally { try { conn . c l o s e ( ) ; } catch ( E x c e p t i o n ex ) { ; } } @Override protected void doGet ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) throws S e r v l e t E x c e p t i o n , IOException { processRequest ( request , response ) ; } @Override protected void doPost ( H t t p S e r v l e t R e q u e s t r e q u e s t , H t t p S e r v l e t R e s p o n s e r e s p o n s e ) throws S e r v l e t E x c e p t i o n , IOException { processRequest ( request , response ) ; } } @Override public S t r i n g g e t S e r v l e t I n f o ( ) { return " S h o r t ␣ d e s c r i p t i o n " ; } // </ e d i t o r −f o l d > 11.4 ábra: JasperServlet 116 JasperReports 12. Képek és rajzok beszúrása

Képek és rajzok beszúrása A kiadvány utolsó cikkében röviden bemutatjuk a riportokban használható grafikai elemek használatát. Ilyet már a korábbi cikkekben is használtunk (vízjel, téglalap) Ebben a rövid cikkben csak bemutatni szeretnénk néhány lehetőséget, külön magyarázat nélkül. A 12-1 Programlista egy olyan jrxml fájl, amibe néhány tipikus grafikus elemet tettünk, ezeket a JasperReports out-of-box szolgáltatja: • vonal, téglalap, ellipszis, • egy kép megjelenítése, 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 • különféle vonalkódok megjelenítése, • a frame (keret) egy speciális lehetőség az összetartozó elemek együttes kezelésére, • Google térkép • HTML tartalom részlet. Az előállított riportot (annak summary sávját) a 12.1 ábra mutatja // 12 −1. P r o g r a m l i s t a : Az Orszagok−Image jrxm <?xml version=" 1 . 0

" e n c o d i n g="UTF−8" ?> <j a s p e r R e p o r t xmlns=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s " x m l n s : x s i=" h t t p : //www w3 o r g / 2 0 0 1 /å XMLSchema−i n s t a n c e " x s i : s c h e m a L o c a t i o n=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s ␣ h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / xsd / j a s p e r r e p o r t xsd " name=" Orszagok−Chart−C r o s s t a b " l a n g u a g e=" g r o o v y " å pageWidth=" 595 " p a g e H e i g h t=" 842 " columnWidth=" 535 " l e f t M a r g i n=" 20 " r i g h t M a r g i n=" 20 " t o p M a r g i n=" 20 " å bottomMargin=" 20 " u u i d=" 5 1 0 3 0 eb1 −4516−48 e2−a63d −04 d952 6ab4 37 "> <p r o p e r t y

name=" i r e p o r t . zoom" v a l u e=" 1 0 " /> <p r o p e r t y name=" i r e p o r t . x " v a l u e=" 0 " /> <p r o p e r t y name=" i r e p o r t . y " v a l u e=" 0 " /> < s t y l e name=" C r o s s t a b ␣ Data ␣ Text " h A l i g n=" C e n t e r " /> <s u b D a t a s e t name=" d a t a s e t 1 " u u i d=" 094 aae7d−c577 −4861−9d68 −584 a 1 e 5 d 7 0 c 5 " /> <q u e r y S t r i n g> < ! [CDATA[ s e l e c t ∗ from o r s z a g o k where t e r u l e t > 2 0 0 0 0 0 0 o r d e r by FOLDR HELY, KAT ] ] > </ q u e r y S t r i n g> <summary> <band h e i g h t=" 704 "> < e l l i p s e> <r e p o r t E l e m e n t u u i d=" f 7 1 1 e a c 1 −8a6d−4c95 −9c41−a 7 b a 1 5 9 6 6 4 5 f " x=" 18 " y=" 40 " w i d t h=" 46 " h e i g h t=" 20 " />

</ e l l i p s e> < e l l i p s e> <r e p o r t E l e m e n t u u i d=" 7 5 5 9 5 8 dd−7f a 3 −478e−a f 3 c −17 e e e d 1 a c 7 e 5 " x=" 187 " y=" 40 " w i d t h=" 46 " h e i g h t=" 20 " /> </ e l l i p s e> <componentElement> <r e p o r t E l e m e n t u u i d=" 0099 a f 2 9 −4890−4b26 −92c8−b 1 f 3 b 0 e 6 a e 4 5 " x=" 54 " y=" 112 " w i d t h=" 200 " h e i g h t=" 50 " /> <j r : C o d e 1 2 8 x m l n s : j r=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s / components " x s i : s c h e m a L o c a t i o n=å " h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s / components ␣ h t t p : // j a s p e r r e p o r t s s o u r c e f o r g e n e t å / xsd / components . xsd " t e x t P o s i t i o n=" bottom

"> < j r : c o d e E x p r e s s i o n>< ! [CDATA[ 1 2 3 4 5 6 7 8 ] ] ></ j r : c o d e E x p r e s s i o n> </ j r : C o d e 1 2 8> </ componentElement> < r e c t a n g l e r a d i u s=" 10 "> <r e p o r t E l e m e n t u u i d=" 7 d9510d1 −3a1e −476a−88 f 1 −b 6 4 b 8 9 2 0 c 6 d 5 " x=" 54 " y=" 227 " w i d t h=" 100 " h e i g h t=" 20 " å b a c k c o l o r=" #009900 " /> </ r e c t a n g l e> < l i n e> <r e p o r t E l e m e n t u u i d=" e 3 3 0 f 4 e 3 −d7a8 −4a7c−bcb8−c 8 a 0 6 7 c 1 1 6 b 5 " x=" 75 " y=" 27 " w i d t h=" 100 " h e i g h t=" 49 " /> </ l i n e> < r e c t a n g l e> <r e p o r t E l e m e n t u u i d=" f 2 6 3 1 a 4 e −b597 −4a ec−b683−f a 5 1 6 6 c f 8 4 6 5 " x=" 54 " y=" 185 " w i d t h=" 100 "

h e i g h t=" 20 " å b a c k c o l o r="#FF0033 " /> </ r e c t a n g l e> <componentElement> <r e p o r t E l e m e n t u u i d=" c 2 6 8 4 8 c 4 −552 f −4489−bb75−d 4 6 3 e d 2 5 2 d 3 4 " x=" 308 " y=" 27 " w i d t h=" 200 " h e i g h t=" 200 " /> <mp:map xmlns:mp=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s / components " x s i : s c h e m a L o c a t i o n="å h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / j a s p e r r e p o r t s / components ␣ h t t p : // j a s p e r r e p o r t s s o u r c e f o r g e n e t /å xsd / components . xsd "> <m p : l a t i t u d e E x p r e s s i o n>< ! [CDATA[ 4 7 . 5 0 1 1 1 5 1 6 5 7 f ] ] ></ m p : l a t i t u d e E x p r e s s i o n> <m p : l o n g i t u d e E x p r e s s i o n>< ! [CDATA[ 1 9 . 0 5 3 1 9 6 5

1 4 5 f ] ] ></ m p : l o n g i t u d e E x p r e s s i o n> </mp:map> </ componentElement> <f r a m e> 117 JasperReports 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 Képek és rajzok beszúrása <r e p o r t E l e m e n t u u i d=" 782 e7b7b −4aed −4ba8 −875b−ddd916d9b99d " s t r e t c h T y p e=" R e l a t i v e T o T a l l e s t O b j e c t " x=" 64 " å y=" 264 " w i d t h=" 122 " h e i g h t=" 44 " f o r e c o l o r="#3300FF" /> <s t a t i c T e x t> <r e p o r t E l e m e n t u u i d=" 57 a2 4 0 0c −5c52 −4564−b8b2−7e 1 9 3 4 7 e e a c 1 " x=" 14 " y=" 14 " w i d t h=" 100 " h e i g h t=" 20 " /> <t e x t E l e m e n t /> <t e x t>< ! [CDATA[ S t a t i c t e x t ] ] ></ t e x t> </ s t a t i c T e x t> </ f r a m e> <componentElement>

<r e p o r t E l e m e n t u u i d=" 4 4 4 6 3 9 ea −5513−4531− b f 9 4 −c 7 8 1 a 4 8 e 1 d 3 1 " x=" 275 " y=" 281 " w i d t h=" 200 " h e i g h t=" 200 " /> <h c : h t m l x m l n s : h c=" h t t p : // j a s p e r r e p o r t s . s o u r c e f o r g e n e t / htmlcomponent " x s i : s c h e m a L o c a t i o n=" h t t p : //å j a s p e r r e p o r t s . s o u r c e f o r g e n e t / htmlcomponent ␣ h t t p : // j a s p e r r e p o r t s s o u r c e f o r g e n e t / xsd / htmlcomponent å xsd " s c a l e T y p e=" R e t a i n S h a p e " h o r i z o n t a l A l i g n=" L e f t " v e r t i c a l A l i g n=" M i d d l e "> <h c : h t m l C o n t e n t E x p r e s s i o n>< ! [CDATA[" < h1>Alma</h2>" ] ] ></ h c : h t m l C o n t e n t E x p r e s s i o n> </ h c : h t m l> </ componentElement> <image>

<r e p o r t E l e m e n t u u i d=" 01 b10e2d −37e2 −48b8−9e95−a b 5 a 9 3 3 4 8 b 8 0 " x=" 22 " y=" 327 " w i d t h=" 211 " h e i g h t=" 154 " /> <i m a g e E x p r e s s i o n>< ! [CDATA[ " / home/ l a z . j p g " ] ] ></ i m a g e E x p r e s s i o n> </ image> </ band> </summary> </ j a s p e r R e p o r t> 12.1 ábra: Grafikai elemek 118 JasperReports Képek és rajzok beszúrása Néhány kiegészítést érdemes tenni a fenti riportban lévő komponensek mostani konkrét használatáról: • A 2 darab ellipszist a 15-20 sorok között adtuk meg. • A vonalat a 30-32 sorok között definiáltuk. • A vonaldiagram megadását a 21-26 sorok között látjuk. A megjelent 12345678 értéket a 24 sor tartalmazza, de itt bármilyen ismert JasperReports kifejezés is megadható lett volna. • A zöld lekerekített téglalap a 27-29 sorok eredménye. • A

piros téglalap specifikációjának helye: 33-35 sorok. • A Google Maps elem megadását a 36-42 sorok tartalmazzák, látható ahogy megadtuk a koordinátákat is, amik természetesen szintén lehetnek dinamikusan kiszámított értékek. A térkép komponensnek több más paramétere is van, például a zoom, de mi most csak az alapértelmezést használtuk. • Az 51-56. sorok között található a HTML komponens. • Végezetül a beszúrt kép az 57-60 sorok terméke. Az 59 sor egy kifejezésként tartalmazza a képfájl helyét, így itt is dinamikusan, akár soronként is változtatható egyegy kép, ami például egy termék katalógus jelentésnél biztosan nagyon jól jön. 12.2 ábra: http://communityjaspersoftcom/ 119