# Jasper-Reports & iReport - Verbindung zur Datenquelle



## henning-malaysia (12. April 2005)

Um mit iReport testweise einen Dummy-Report zu erstellen, habe ich mir selber ein minimales XML-File folgenden Inhaltes angelegt:


```
<iReportProperties>
  <person>
          <name>Mustermann</name>
          <vorname>Anton</vorname>
  </person>
  <person>
          <name>Musterfrau</name>
          <vorname>Antonia</vorname>
  </person>
  </iReportProperties>
```

In iReport habe ich dann eine neue XML-File-Datenquelle zu dieser Datei angelegt. Im Report habe ich die Felder $F{name} und $F{vornamename} angelegt, in der Hoffnung, dass sich selbige mit "Mustermann" und "Anton" füllen würden. 

Ich bekam daraufhin beim Kompilieren nicht das gewünschte Resultat, dafür unten in der Fehlerkonsole die für mich etwas unerklärliche Meldung
Compiling to file... M:\jasper\output\test1iRep.jasper -> M:\jasper\output\untitled_report_1.java 
CannotfindlibiniReporthomedirectory(.)
CannotfindlibiniReporthomedirectory(.) (2x)

Kann jemand mit der Fehlermeldung etwas anfangen, und kann mir jemand sagen, ob meine Vorgehensweise, den Report mit Daten zu füllen, grundsätzlich falsch ist bzw. was ich anders machen muss? Wäre sehr dankbar, denn ich muss das hier für meine Arbeit machen, allerdings gibt es niemanden, der sich auch nur etwas mit der Materie auskennt. O-Ton-Chef: Schau halt mal im Netz. 

Also, bitte lasst mich nicht zappeln. Dankeschön!

henning-malaysia


----------



## takidoso (12. April 2005)

Grüß Dich,
Ich selbst habe Dein Problem zwar noch nicht gehabt, aber ich arbeite gelegentlich mit IReport und Jasper-Repot.
(Sei froh, dass dieses Tool existiert, denn anfangs mußte man die XML-Files händisch erstellen, da wird man auf die Dauer ziemlich kürre!)
Wenn ich Deine Fehlermeldung so anschaue sieht es so aus, dass IReport vielleicht noch von Dir in irgendeinerweise konfiguriert werden sollte. Du hast mehr Chancen in der Jasper-Report Gemeinde da sinnvolle Antworten zu erhalten, Du kannst Dich in der Mailingliste unter https://lists.sourceforge.net/lists/listinfo/jasperreports-questions
eintragen.

Viel Glück

Takidoso


----------



## takidoso (12. April 2005)

Noch eine kleine Erläuterung zur prinzipiellen Vorgehensweise von Jasper-Reports und dem Zusammenspiel mit IReports...

JasperReport benötigt um Reports zu erstellen XML-Files, die den zu erstellenden Report definerien. Dieses XML-File wird dann mittels des Jasper-Report-Compilers in eine .jasper Datei übersetzt, die meineswissens nichts anderes ist als ein .class File in Java.
Es gibt nun verschiedene Möglichkeiten einer Datenquelle für solche Jasper-Reports. Entweder man hat in dem Report eine Datenbankverbindung angegeben mit entsprechendem SQL-Statement, vorin ich bisher allerdings keinerlei Erfahrung habe, oder man gibt dem Report Java-programmatisch seine anzuzeigenden Daten, was ich gewöhnlicherweise mache. Das Jasper-Report API bietet recht bequeme Möglichkeiten einen solchen Report am Bildschirm anzuzeigen mit Möglichkeit denselben auch druch den Anwender getriggert auszudrucken oder auch in z.B. einem PDF-File und auch anderen Formaten auszugeben.

Der Editor IReport ist im wesentlichen dazu da, das oben genannte XML-File zu erstellen und betätigt auch gleichzeitig den Jasper-Report Compiler, den man wenn man will auch selbst in eigenen Java-Anwendungen anstoßen kann. Wichtig ist hierbei dass man die .jasper-Datei benötigt um den tatsächlichen Report zu erstellen.

Hier ein bissle Code in Form einer tatsächlich verwendetetn Klasse in einem meiner Anwendungen:

```
package de.mc.etnbestterm.gui;

import java.awt.*;
import java.net.*;
import java.util.*;
import java.text.*;
import java.math.*;
import javax.swing.*;
import javax.swing.table.*;

import net.sf.jasperreports.view.*;
import net.sf.jasperreports.engine.*;
import net.sf.jasperreports.engine.data.*;

import de.mc.util.*;

import de.mc.etnbestterm.util.*;
import de.mc.etnbestterm.data.*;

.....
public class FallAktenResumeePanel extends SingleTablePanel implements FallAktenConstants
{
    private BorderLayout      m_borderLayout  = new BorderLayout();
    private JRViewer          m_viewer;
    private DefaultTableModel m_tModel        = new DefaultTableModel();
    private JLabel            m_leerLabel     = new JLabel("Kein Beleg vorhanden!");

    private Properties        m_props         = SingletonManager.getMainPropertiesClient();
    private Properties        m_tempProps     = SingletonManager.getTempProperties();
    private String            m_urlStr;

    public FallAktenResumeePanel()
    {
        this.setLayout(m_borderLayout);
        m_urlStr = m_props.getProperty("URLSTR_REPORT_STUFF",
                                     m_tempProps.getProperty("URLSTR_SOURCE_SERVER")
                                     +GlobalConstants.SUBPATH_REPORT_STUFF);

    }

    /**
     * Es wird die Fallakte mit Hilfe der gegebenen FallId ermittelt und
     * ihre Artikeleinzelpreise  mit den Mengen multipliziert
     * und somit die jeweiligen Positionswerte errechnet
     * Anschließend wird die Fallakte als Report im Fenster dargestellt.
     * ist fallId "" oder null wird lediglich ein Label mit "Kein Beleg vorhanden"
     * auf der Fensteroberfläche angezeigt.
     * @param fallAkte Map beinhaltet folgende Parameter für den Report
     * @see de.mc.etnbestterm.util.FallZuColIndexing
     * @throws Exception
     */
    public void setReport(String fallId) throws Exception
    {
        if (fallId != null)
        {
            // achtung Reihnfolge muß mit FallDokuPanel übereinstimmen
            Vector columnNames = new Vector(14);
            columnNames.add("ROW-ID");
            columnNames.add("Fall-Nr");
            columnNames.add("Artikel-ID");
            columnNames.add(FLD_ARTIKELNR);
            columnNames.add(FLD_ARTIKELBEZ);
            columnNames.add(FLD_LIEFERANT);
            columnNames.add(FLD_CHARGE);
            columnNames.add(FLD_SERIENNR);
            columnNames.add(FLD_VERBRDATUM);
            columnNames.add(FLD_MENGE);
            columnNames.add(FLD_ME);
            columnNames.add(FLD_WERT);
            columnNames.add(FLD_KOSTENSTELLE);
            columnNames.add(FLD_OE);

            Vector data = SingletonManager.getOrderDataHolder().getFallDoku(fallId);
            m_tModel.setDataVector(data, columnNames);

            // Gesammtsumme ermitteln und Positionswerte durch Multiplikation mit Menge korrigieren
            BigDecimal gw = new BigDecimal(0);
            for (int i=0; i<data.size(); i++)
            {
                BigDecimal p  = (BigDecimal) m_tModel.getValueAt(i, FallZuColIndexing._COLIDX_PREIS);
                Integer    m  = (Integer)    m_tModel.getValueAt(i, FallZuColIndexing._COLIDX_MENGE);
                BigDecimal pw = p.multiply(new BigDecimal(m.toString()));
                gw = gw.add(pw);
                m_tModel.setValueAt(pw, i, FallZuColIndexing._COLIDX_PREIS);
            }
            Map fallAkte = new HashMap();
            fallAkte.put(PAR_FALLNR, fallId);
            fallAkte.put(PAR_GESAMTSUMME, gw);
            fallAkte.put(PAR_TITELLOGO,   m_urlStr+"/providerReportLogo.gif");
            fallAkte.put(PAR_INSTITUT, SingletonManager.getKundenHaus().getHausName());

            URL viewMetaFile = new URL(m_urlStr + "/FallakteHBReport.jasper");

            JasperPrint jp = JasperFillManager.fillReport(viewMetaFile.openStream(),
                                                          fallAkte,
                                                          new JRTableModelDataSource(m_tModel));
            remove(m_leerLabel);
            if(m_viewer != null)
            {
                remove(m_viewer);
            }
            m_viewer = new JRViewer(jp);
            add(m_viewer, BorderLayout.CENTER);
            this.repaint();
        }
        else
        {
            if(m_viewer != null)
            {
                remove(m_viewer);
            }
            add(m_leerLabel, BorderLayout.CENTER);
            this.repaint();
        }
    }// end of setReport(Map)
}
```
dies soll nur grob zeigen wie man programatisch einen Jasper-Report mittels eines Tabellenmodels Daten übergibt.

ich hoffe das gab einen kleinen groben Einblick

Takidoso


----------



## henning-malaysia (18. April 2005)

Sorry, hat ein bisschen gedauert, bis ich zum Antworten kam...

Erstmal vielen Dank für Deine Info. Die "Jasper per Javaprogramm mit Daten füttern"-Lösung wäre in meinen Augen die beste, leider kann ich sie für meine Zwecke nicht benutzen. Ich habe die Vorgabe, dass das bestehende ERP-Programm die Daten exportieren soll. Diese Exportschnittstelle speziell für Jasper existiert bereits, nur funktioniert sie nicht bzw. ich weiß offenbar nicht wie. 

Aber ich werde die Sau schon noch kriegen  

Gruß vom Äquator
henning-malaysia


----------



## takidoso (19. April 2005)

Tja das ist eine gute Frage warum die nicht funktioniert. Aber was für eine Exportschnittstelle ist es denn eigetnlich so prinzipiel?
Wird eine Datei geschrieben oder wird etwas in einer DB-Tabelle hinterlassen oder gibt es ein API für diese Ausgabeschnittstelle des ERPs?

mit Mitteleuropäischen Grüßen

Takidoso


----------



## henning-malaysia (20. April 2005)

Die Exportschnittstelle soll wohl, wie ich das verstanden habe, einen XML-Export von den Daten und auch ein Standard-Layout-File erzeugen. Um dieses Layout den individuellen Bedürfnissen anzupassen, würde ich dann iReport benützen. Dass das Ganze nicht   ist natürlich mehr ein Problem der ERP-Software (ABAS), möglicherweise ist nur etwas falsch konfiguriert. 
Ein Direktzugriff z.B. per SQL auf die Datenbank des ERP-Systems scheint nicht vorgesehen und aus nachvollziehbaren Gründen auch nicht gewünscht zu sein. 

Meine eingangs beschriebenen Versuche mit dem eigenen XML-File dienten eigentlich nur dem Zweck, zu verstehen, was bei der ganzen Sache abläuft. Leider ist es mir aber nach wie vor nicht gelungen, selber einen Mini-Report mit XML-File als Datenquelle erfolgreich zu erstellen. Aber so schnell gebe ich natürlich nicht auf...

Gruß

henning-malaysia


----------



## ATha1 (15. Juli 2005)

Also wenn ich das richtig verstehe benötigst du etwas, damit du aus einem bestehenden XML File bzw. einen Stream mit XML Daten, wenns über eine Schnittstelle geht, die Daten in einen Jasper Report bekommst.

Und wo läuft das JasperReport Tool?
oder seid ihr dabei so ein Tool zu schreiben, welches dann eine Schnittstelle ins SAP hat?

Tja ich würde dann sagen, im Schlimmsten Fall einfach die über die Schnittstelle kommende XML umwandeln in eine Bean Collection oder ein Bean Array, und dann als Datasource eine JRBeanArrayDataSource bzw. JRBeanCollectionDataSource verwenden oder auch gleich selbst eine solche Klasse erstellen die JRAbstractBeanDataSource erweitert.

Ich hoffe ich konnte dir damit etwas weiterhelfen.


----------



## henning-malaysia (27. Juli 2005)

Ja, danke, das ist ein guter Hinweis. Wir verfolgen verschiedene Ansätze, einer davon ist, wie von Dir beschrieben, dass wir selber ein Tool schreiben. 
Bin allerdings in letzter Zeit nicht mehr viel dazu gekommen, weil es soviel anderes Zeug zu tun gibt. Aber die BeanClassen werd ich mir mal genauer anschaun. 

Gruß

henning-malaysia


----------



## ATha1 (28. Juli 2005)

Naja es muss ja nicht gleich ein ganzes Tool sein.

Ich denke da lediglich an ein paar Klassen, die den XML Parser beinhalten, und der Parser wandelt den Input um in dementsprechende Java Objekte, welche dann direkt Jasper übergteben werden können.

Denke mal die Größte Arbeit wird in der Entwicklung des XML Parsers stecken.
Der Rest sollte nicht so umfangreich sein.


----------

