# Jasper Reports, iReport



## Romy (23. Jun 2010)

Hallo,

ich habe ein paar Probleme mit iReport und hoffe, dass mir hier jemand weiterhelfen kann.

Das erste Problem ist, dass ich in iReport eine Vorlage erstellt habe und über eclipse diesen Report mit Daten versorge. Das sind allerdings Daten die alle auf eine Seite passen, er gibt mir allerdings 3 Seiten mit genau dem gleichen Inhalt aus... Jetzt habe ich gerade gemerkt, dass das wohl an diesem Detail1 Bereich liegt. Wenn ich diesen größer ziehe, gibt er mir mehr Seiten aus, wenn ich ihn ganz klein ziehe nur eine Seite.

Also ich bin wirklich absolute Laie in diesem Gebiet und auch in XML kenne ich mich noch nicht wirklich aus, deswegen hoffe ich, es gibt hier jemanden, der da etwas Licht ins Dunkle bringen kann?

Gerade hab ich mich gewundert wieso er meien Seitenzahl nur 1x ausgibt bis ich darauf gekommen bin, dass diese in den footer Bereich muss. Anscheinend haben da alle Daten ihren ganz bestimmten Platz - nur woher weiß ich welchen?

Dann wäre noch die Frage, für was Subreports da sind und wie ich diese korrekt in den vorhandenen Report einbinden kann?

Okay ich glaube das waren erstmal alle Frage, wäre schon super wenn mir da jemand weiterhelfen könnte.

Danke schonmal.

Liebe Grüße

Romy


----------



## thE_29 (23. Jun 2010)

Am besten mal die Tutorials hier durchmachen: 
JasperForge: iReport Project Home

Wie du schon richtig gemerkt hast, sind Footer und Header für bestimmte Sachen da (so wie bei Word-docs).
Subreports sind "Teilreports" die man nach belieben platziere kann.
Wenn du zB 10mal den gleichen Block an Daten im Bericht brauchst, wirst du den nicht 10mal eintragen, sondern machst einen Report und hängst den als Subreport rein.

Das mit den Seiten, wann wo was drüberspringt weiß ich leider nicht.. Mein letzter iReport ist 2-3 Jahre her..


----------



## Romy (23. Jun 2010)

Ah super, danke 

Weißt du vllt. auch an was es liegen kann, das meine Daten die ich übergebe nicht in den Fields angezeigt werden?

Bei Parametern funktioniert das super, nur das er mir da immer nur den ersten Datensatz ausgibt... dann habe ich gelesen, dass man dafür Fields braucht, allerdings kommt bei mir dann immer die Fehlermeldung, dass er dieses Field nicht kennt...

Langsam bin ich echt am verzweifeln... =(

Trotzdem schonmal danke für deine Hilfe, werde mir die Seite mal anschauen!


----------



## y0dA (23. Jun 2010)

Für "Fields", welche im Detailbereich angezeigt werden, brauchst du eine Datasource.
bspw. mit 
	
	
	
	





```
JRBeanCollectionDataSource(java.util.Collection beanCollection)
```

**EDIT**

Nochmal genauer:
Parameter sind Werte welche du, im Idealfall, nur einmal im Bericht oder pro Seite benötigst (Dinge die im Headerbereich stehen etc.).
Fields benutzt du im Detailbereich, sprich hier wird über eine Collection iteriert - hier kommen deine Listendaten hier, bspw. eine Aufzählung von Kostenstellen, was weiß ich.


----------



## Romy (24. Jun 2010)

Hey super Danke!

Vielleicht bringt mich ja das ganze ein bisschen weiter =)


----------



## Romy (24. Jun 2010)

Okay ich raffs wohl doch nicht.

Hast du vielleicht ein Beispiel für mich, wie das ganze aussehen kann?


----------



## y0dA (24. Jun 2010)

Romy hat gesagt.:


> Okay ich raffs wohl doch nicht.
> 
> Hast du vielleicht ein Beispiel für mich, wie das ganze aussehen kann?



Was für ein Beispiel?
Ein jrxml und oder Java Code?

Du musst hald doch ein bisschen genauer sein bzw. eventuell mal deinen Code herzeigen.

Ich will mal nicht so sein und dir, obwohl deine Fragen fast schon bissl frech sind, ein wenig weiterhelfen.

So könnte bspw. eine Methode aussehen die einen Bericht erzeugt:

```
public static JasperPrint fooBericht(
			ObjektFuerBericht objFuerBericht, Timestamp aktuell) {
		        // Die Liste eine Arraylist welche meine Daten fuer den Detailbereich beinhaltet - Fields!
                        JRDataSource ds = new JRBeanCollectionDataSource(objFuerBericht
				.getListeFuerDetailBereich());
		Map<String, Object> param = new HashMap<String, Object>();
		JasperPrint jasperPrint = null;

		try {
			param.put(PARAMETER_NAME_WIE_IM_JRXML,
					"Ich bin ein Parameter");
			
			//hier uebergibst du dem Bericht deine Parameter Liste sowie die Datasource fuer den Detailbereich
                        jasperPrint = JasperFillManager.fillReport((JasperReport) JRLoader
					.loadObject("Pfad zum Bericht", param,
					ds);
		} catch (JRException e) {
			e.printStackTrace();
		}

		return jasperPrint;
	}
```
Dadurch wird dann im iReport, in deinem Bericht, die DS erkannt - die Fields müssen aber genau so heissen wie im Java Objekt welches eine Zeile in deinem Detailbereich repräsentiert. Weiters musst du halt noch den Klassenpfad im iReport setzen damit selbiges die Klassen kennt:
Optionen --> Klassenpfad --> Pfad zu den Klassen oder Package.


----------



## Romy (24. Jun 2010)

Hallo,

danke für dein Beispiel. Weiß zwar nicht wieso meine Fragen frech sein sollten, aber falls irgendwas falsch rüberkommen ist tut es mir leid.

Mit den genaueren Angaben hast du natürlich Recht.

In meinem Main habe ich eine Hashmap die ich mit Daten fülle. Danach rufe ich die Methode aus meiner Klasse auf und übergebe die Hashmap, die XML-Datei und die PDF-Datei in die er schreiben soll:


```
r.FillReportFromHashtable(hashmap, "C:\\report2.jrxml", "C:\\Example1.pdf");
```

Meine Methode sieht dann bisher so aus:


```
public void FillReportFromHashtable(HashMap<String, String> hashmap, String xmlpfad, String outputpfad )
	{
        
		try
		{
			jasperReport = JasperCompileManager.compileReport(xmlpfad);

			jasperPrint = JasperFillManager.fillReport(jasperReport,hashmap, new JREmptyDataSource());
		
			JasperExportManager.exportReportToPdfFile(jasperPrint,outputpfad);
			
			JasperDesignViewer jdv = new JasperDesignViewer(jasperReport);
			
			jdv.show();
		}
		catch(JRException e)
		{
			e.printStackTrace();
		}
	}
```

Und in meinem Report habe ich dann Fields in Detailbereich angelegt und sie nach den Parametern der Hashmap benannt und bei den Eigenschaften den Key auch noch auf diesen Parameter gesetzt.

So ich hoffe das war jetzt etwas ausführlicher, ich werde jetzt auf jeden Fall mal versuchen mit deinem Beispiel weiterzukommen.

Danke schonmal für deine Hilfe!


----------



## y0dA (24. Jun 2010)

Meinte mit "Frech" nur dass du, zumindest wirkte es in den ersten beiden Posts so, die Arbeit jemand anderem machen lassen wolltest - sprich es kamen keine Infos von dir und wir sollten dir hier schnell mal alles über Jasper zeigen. Der gepostete Link beinhaltet eigentlich eh alle deine Fragen.

Bei deinem Code übergibst du aber KEINE Datasource, bzw befüllst den Bericht mit einer JREmptyDataSource, was bedeutet dass der Bericht keine Daten für den Detailbereich bekommt - also keine Fields.

Du musst statt:

```
jasperPrint = JasperFillManager.fillReport(jasperReport,hashmap, new JREmptyDataSource());
```

sowas schreiben:

```
JRDataSource ds = new JRBeanCollectionDataSource(objFuerBericht
                .getListeFuerDetailBereich());
jasperPrint = JasperFillManager.fillReport(jasperReport,hashmap, new JREmptyDataSource());
```
Damit übergibst du dem Bericht eine Datasource die Daten beinhaltet!

Hoffe es klappt nun 

Ahja, die Datasource habe ich eigentlich immer mit einem List Objekt befüllt, kA ob das auch mit einer Hashmap funktioniert, Hashmap hatte ich nur für die Parameter.


----------



## Romy (24. Jun 2010)

Super ich danke dir ;-)

Tut mir leid wegen meiner ersten Posts, ich bin langsam wirklich deprimiert und demotiviert, was diese Sache angeht weil ich einfach nicht vorwärts komme. Aber ich denke dank deiner Hilfe sollte ich da jetzt endlich weiterkommen


----------



## y0dA (24. Jun 2010)

Ja überhaupt kein Problem, musste mich vor 1 1/2 Jahren auch von 0 auf 100 in Jasperreports einarbeiten und weiß wie frustrierend es sein kann - zumal ich mit Jasperreport Dinge getan habe für welche es gar nicht konzipiert ist/war.

Also wenns noch was gibt kannst mich ruhig anschreiben, grad bei Jasperreports helfe ich gerne.


----------



## Romy (24. Jun 2010)

Danke! Bist echt super! 

Es sieht jetzt so bei mir aus:


```
try
		{
			HashMap<String, String> hm = new HashMap<String, String>();
			
			XdevList daten = null;
		
			for(int i = 0;i<vt.getRowCount();i++)
			{
				daten = vt.getRowAsList(i);
				
				System.out.println(daten.toString());
			}

			if(daten != null)
			{
				jasperReport = JasperCompileManager.compileReport(xmlpfad);
				
				JRDataSource ds = new JRBeanCollectionDataSource(daten);
				
                                try 
				{
		                       hm.put("aParam", "Ich bin ein Parameter");

		                       jasperPrint = JasperFillManager.fillReport(jasperReport, hm,ds);
		                 } 
				catch (JRException e) 
				{
		                       e.printStackTrace();
		                }

	
				JasperExportManager.exportReportToPdfFile(jasperPrint,outputpfad);
				
				JasperDesignViewer jdv = new JasperDesignViewer(jasperReport);
				
				jdv.show();
			}
		}
		catch(Exception e)
		{
			e.printStackTrace();
		}
```

Muss ich den Parameter in der XML Datei auch irgendwo erwähnen? Den bräuchte ich ja rein theoretisch gar nicht.

Ausgeben sollte er eigtl. 2 Datensätze aus einer Datenbank mit den Feldern: id, name, vorname, wohnort, alter

Dann bringt er mir allerdins diese Fehlermeldung :noe:


```
net.sf.jasperreports.engine.JRException: Error retrieving field value from bean : id
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:123)
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getFieldValue(JRAbstractBeanDataSource.java:96)
	at net.sf.jasperreports.engine.data.JRBeanCollectionDataSource.getFieldValue(JRBeanCollectionDataSource.java:100)
	at net.sf.jasperreports.engine.fill.JRFillDataset.setOldValues(JRFillDataset.java:823)
	at net.sf.jasperreports.engine.fill.JRFillDataset.next(JRFillDataset.java:787)
	at net.sf.jasperreports.engine.fill.JRBaseFiller.next(JRBaseFiller.java:1478)
	at net.sf.jasperreports.engine.fill.JRVerticalFiller.fillReport(JRVerticalFiller.java:125)
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:942)
	at net.sf.jasperreports.engine.fill.JRBaseFiller.fill(JRBaseFiller.java:860)
	at net.sf.jasperreports.engine.fill.JRFiller.fillReport(JRFiller.java:84)
	at net.sf.jasperreports.engine.JasperFillManager.fillReport(JasperFillManager.java:624)
	at Reportaction.FillReportFromVT(Reportaction.java:81)
	at Anwendung.main(Anwendung.java:46)
Caused by: java.lang.NoSuchMethodException: Unknown property 'id' on class 'class java.lang.Integer'
	at org.apache.commons.beanutils.PropertyUtilsBean.getSimpleProperty(PropertyUtilsBean.java:1313)
	at org.apache.commons.beanutils.PropertyUtilsBean.getNestedProperty(PropertyUtilsBean.java:762)
	at org.apache.commons.beanutils.PropertyUtilsBean.getProperty(PropertyUtilsBean.java:837)
	at org.apache.commons.beanutils.PropertyUtils.getProperty(PropertyUtils.java:426)
	at net.sf.jasperreports.engine.data.JRAbstractBeanDataSource.getBeanProperty(JRAbstractBeanDataSource.java:111)
	... 12 more
net.sf.jasperreports.engine.JRException: No input source supplied to the exporter.
	at net.sf.jasperreports.engine.JRAbstractExporter.setInput(JRAbstractExporter.java:845)
	at net.sf.jasperreports.engine.export.JRPdfExporter.exportReport(JRPdfExporter.java:259)
	at net.sf.jasperreports.engine.JasperExportManager.exportReportToPdfFile(JasperExportManager.java:122)
	at Reportaction.FillReportFromVT(Reportaction.java:90)
	at Anwendung.main(Anwendung.java:46)
```

Vorher kam, "Report Design not valid", dann habe ich die Fields nochmal auf eine andere Art hinzugefügt, dann war der Fehler weg und der oben kam... Findet er das Feld immernoch nicht? Ich glaube je mehr ich versuche desto falscher wirds 

Aber immerhin weiß ich jetzt schon mehr wie vorher, dank dir :toll:


----------



## y0dA (24. Jun 2010)

1. Was ist 
	
	
	
	





```
XdevList
```
, ist das eine Kindklasse einer Collection?
Warum nimmst du nicht einfach eine 
	
	
	
	





```
List<Object>
```
 - wie auch in meinem Beispiel gezeigt.

2. Ob du Parameter übergeben musst kann ich dir nicht sagen, habe immer welche benötigt - nochmal *Parameter* sind die statischen Werte deines Berichts, du wirst ja einen Headerbereich haben und dort vllt etwas ausgeben wollen was nur zur Laufzeit bekannt ist, eben einen Parameter. Weiters benutzt du ja sicher iReport? Falls ja, kannst du ja alles bequem visuell lösen. Ich kenne den aktuellen iReport nicht aber "damals" konnte man im iReport, in deinem Bericht, in der *Dokumentstruktur* Parameter sowie Fields und Variablen erstellen. Dort musst du auch die Parameter bekannt geben, selbiges wirst du ja hoffentlich schon für die Fields gemacht haben oder?

3.
_
Ausgeben sollte er eigtl. 2 Datensätze aus einer Datenbank mit den Feldern: id, name, vorname, wohnort, alter
Dann bringt er mir allerdins diese Fehlermeldung 
_

```
XdevList daten = null;
        
            for(int i = 0;i<vt.getRowCount();i++)
            {
                daten = vt.getRowAsList(i);
                
                System.out.println(daten.toString());
            }
```
Wie schon erwähnt, kenne ich die Struktur der Klasse 
	
	
	
	





```
XdevList
```
 nicht jedoch sieht mir dieses Konstrukt fehlerhaft aus, da

```
daten = vt.getRowAsList(i);
```
ja eine Zuweisung ist und nicht etwa ein "ein Datensatz hinzufügen" wie bspw. bei:

```
List<Object> list = new ArrayList<Object>();
list.add(new Object());
```

Du könntest mir dein .jrxml sowie deinen Code einmal zukommen lassen, dann könnte ich da auch mal direkt drübersehen, ansonsten lösen wir das Problem halt gemeinsam hier im Thread - was für dich sicher sinnvoller ist.


----------

