Discussion:
JasperReports +ordner mit fonts festlegen.
(zu alt für eine Antwort)
Christian-Josef Schrattenthaler
2008-04-22 21:01:41 UTC
Permalink
Hallo!

Ich muss für die Erstellung der Reports aus einer Anwendung
JasperReports verwenden. Die Jrxml-Dateien müssen mit iReport erstellt
werden, und manuell darf ich da nichts ändern. Weiters muss alles über
den JasperViewer abgewickelt werden.

Jetzt muss der Anwender natürlich die Möglichkeit haben, seine Fonts
in einem speziellen Ordner abzulegen. Ich nehme mal an, dass die
meisten unter Windows C:\Windows\Fonts verwenden dürften, und es macht
meiner Meinung nach nicht viel Sinn, wenn ich den Anwender zwinge die
Fonts für die Anwendung zusätzlich in einem eingenen Ordner abzulegen.

Unter iReports kann ich diesen Ordner verwenden, wenn ich ihn in
meinen Classpath (nicht in den iReport-Klassenpfad!) aufnehme, und ihn
dann als Schriftartenordner kennzeichne. Leider gibt es dann einen
Fehler beim Lesen der Fonts unter Windows Vista, das ist jetzt aber
nebensächlich. Interessant ist vielleicht auch, dass ich nicht den
Klassenpfad von iReport verwenden kann, aber das ist hier auch nicht
so wichtig.

Mein Problem ist, dass wenn ich dann den Report von der Anwendung aus
anspreche, und mit mit dem JasperViewer den Report anzeigen lasse,
dann klapp alles. Wenn ich dann daber das Ganze als PDF-Datei
speichern will, werden die Fonts nicht gefunden. Unter iReports
funktioniert es nur, wenn ich den Ordner der Fonts in den normalen
Java Classpath aufgenommen habe.

Ich habe nun schon mit der jasperreports.properties und einigen
Parametern in der Jrxml-Datei herumexperimentiert, aber ich bekomme es
einfach nicht zum Laufen.

Gruß,
Christian.
Nico Rogowski
2008-04-23 20:06:06 UTC
Permalink
Post by Christian-Josef Schrattenthaler
Mein Problem ist, dass wenn ich dann den Report von der Anwendung aus
anspreche, und mit mit dem JasperViewer den Report anzeigen lasse,
dann klapp alles. Wenn ich dann daber das Ganze als PDF-Datei
speichern will, werden die Fonts nicht gefunden. Unter iReports
funktioniert es nur, wenn ich den Ordner der Fonts in den normalen
Java Classpath aufgenommen habe.
http://www.mail-archive.com/jasperreports-***@lists.sourceforge.net/msg00109.html

Erster Treffer von

http://www.google.de/search?q=jasperreports+pdf+embedding+fonts


Nico
Christian-Josef Schrattenthaler
2008-04-23 20:21:34 UTC
Permalink
Post by Nico Rogowski
Erster Treffer von
http://www.google.de/search?q=jasperreports+pdf+embedding+fonts
Das habe ich alles scho durch, und noch mehr. Das Ganze funktioniert
auch einwandfrei. Jetzt gehen wir aber mal davon aus, dass der
Endanwender den Report per iReport erstellt, und da weis ich ja gar
nicht, in welchem Ordner die Schritart (TTF-Datei) liegt. Das kann man
nur umgehen, wenn der Endanwender den kompletten Pfad (zB
C:\WINDOWS\Fonts\arial.ttf) angibt. Wenn der aber nur arial.ttf
angibt, dann wird nichts gefunden. Ich habe es auch nicht geschafft,
dass ich den Ordner über die Classpath-Variable zugänglich gemacht
habe. Es würde mir schon reichen, wenn ich in meiner Anwendung einen
fixen Ordner (zB Fonts) hätte, in den der Benutzer die TTF-Datei
kopieren muss, aber das habe ich auch nicht geschafft. Ich weis
einfach nicht, wie ich in meiner Anwendung, oder in der Jrxml-Datei
den Ordner mit den Fonts angeben kann, so dass der Benutzer ganz
normal mit iReport arbeiten kann, ohne dann die TTF-Verweise manuell
mit dem gesamten ORdner nachzubessern.

Christian.
Nico Rogowski
2008-04-23 21:31:42 UTC
Permalink
Post by Christian-Josef Schrattenthaler
Ich weis
einfach nicht, wie ich in meiner Anwendung, oder in der Jrxml-Datei
den Ordner mit den Fonts angeben kann, so dass der Benutzer ganz
normal mit iReport arbeiten kann, ohne dann die TTF-Verweise manuell
mit dem gesamten ORdner nachzubessern.
JasperReports nutzt doch iText zur Erzeugung der PDFs?!?

http://itextdocs.lowagie.com/tutorial/fonts/getting/index.php

sagt, daß man für iText Fonts registrieren kann/muss.

FontFactory.register("c:\\windows\\fonts\\comicbd.ttf");

bzw.

FontFactory.registerDirectory("c:\\windows\\fonts");

Natürlich ungetestet.

Nico
Christian-Josef Schrattenthaler
2008-04-24 06:26:05 UTC
Permalink
Post by Nico Rogowski
JasperReports nutzt doch iText zur Erzeugung der PDFs?!?
Ja. Leider noch die 1.x, welche man händisch austauschen kann. Die 2.x
macht aber irgendwie Probleme.
Post by Nico Rogowski
http://itextdocs.lowagie.com/tutorial/fonts/getting/index.php
sagt, daß man für iText Fonts registrieren kann/muss.
FontFactory.register("c:\\windows\\fonts\\comicbd.ttf");
bzw.
FontFactory.registerDirectory("c:\\windows\\fonts");
Darauf habe ich ja keinen Zugriff. Ich lasse den Report im
JapserViewer anzeigen, und von dort aus kann der Benutzer bestimmen,
ob er den Report speichert oder druckt. Wenn er ihn als PDF-Datei
speichert, dann kommt es erst zu dem Problem. Wenn er den kompletten
Pfad zur TTF-Datei im Report angibt ist alles ok. Wenn er aber nur die
TTF-Datei angibt, so wie es iReport automatisch macht, dann wird
nichts gefunden. Ich habe bei iReport auch einige Zeit gebraucht, bis
das über die Classpath-Variable und die zusätzliche Konfiguration
unter iReport richtig funktioniert hat, aber von meiner Anwendung aus
hat das dann nie geklappt, mit dem Classpath.

Da ich ja nicht weis, welche Fonts der Kunde unter iReports (oder wie
auch immer er die Jrxml-Dateien erzeugt) verwendet, kann ich da auch
nicht wirklich was registrieren, oder so eine FontMap erzeugen.

Es wäre schön, wenn ein Entwickler genau das Aussehen der Report
vorhersagen, oder gar fix bestimmen kann. Das ist aber nicht so. Im
aktuellen System habe ich das Problem, dass der Report generator
direkt mit dem Programmiersystem verbunden ist, und so muss ich für
jeden Kundenwunsch selber ran. Ziel wäre es, dass die Kunden Ihre
Reports selbst gestalten, die Jrxml-Datei in einem speziellen ORdner
ablegen, und der Rest passiert automatisch. Hier ist die Angabe der
genauen Position eines TTF-Datei nicht so schlimm, das kapieren die
Kunden schon. Es wäre eben anders schöner gewesen.

Eigenartig ist, dass ich zu diesem Thema viele Beiträge gefunden habe,
aber keiner hat das Problem schön erklärt, oder gar eine brauchbare
Lösung dafür vorgesehen.

iReport hat in der aktuellen Version auch einige Kleinigkeiten die
meiner Meinung nach nicht ganz ok sind, aber es scheint niemanden zu
interessieren, und das System zum Melden von Bugs funktioniert seit
Tagen nicht.

Trotzdem muss ich sagen, dass JasperReports in Verbindung mit iReport
eine tolle Sache ist...

Gruß,
Christian.
Nico Rogowski
2008-04-24 20:55:16 UTC
Permalink
Post by Christian-Josef Schrattenthaler
Post by Nico Rogowski
FontFactory.register("c:\\windows\\fonts\\comicbd.ttf");
bzw.
FontFactory.registerDirectory("c:\\windows\\fonts");
Darauf habe ich ja keinen Zugriff.
Doch. FontFactory#registerDirectory ist eine statische Methode. Die Doku
zu iText sagt:

"Note that all methods in class FontFactory are static. So if you have
different applications in the same JVM, you may discover that there were
more fonts registered than you expected..."

Also müsstest Du eigentlich vor dem Aufruf von JasperReports nur das
vereinbarte FontDirectory registrieren und gut ist.

Außerdem: "It gets even easier if you use registerDirectories(). This
method looks in some probable directories such as c:\windows\fonts,
/usr/X/lib/X11/fonts/TrueType, /usr/X11R6/lib/X11/fonts/ttf, etc... This
works on most Windows, Linux and Solaris systems. (If not, you will have
to go and look for the font files yourself.)"

Sind es also Standardfonts (oder liegen sie in den
Standardverzeichnissen wie c:\windows\fonts), sollte das damit erledigt
sein.
Post by Christian-Josef Schrattenthaler
Da ich ja nicht weis, welche Fonts der Kunde unter iReports (oder wie
auch immer er die Jrxml-Dateien erzeugt) verwendet, kann ich da auch
nicht wirklich was registrieren, oder so eine FontMap erzeugen.
Wenn der Kunde eine jrxml-Datei mit Fonts abliefert, hat er die
dazugehörigen TTF-Dateien mitzuliefern. Die wirfst Du alle in ein
Verzeichnis, das Du zusätzlich registrierst.
Post by Christian-Josef Schrattenthaler
Eigenartig ist, dass ich zu diesem Thema viele Beiträge gefunden habe,
aber keiner hat das Problem schön erklärt, oder gar eine brauchbare
Lösung dafür vorgesehen.
Da ist sicher jeder froh, das Biest bezwungen zu haben.
Post by Christian-Josef Schrattenthaler
Trotzdem muss ich sagen, dass JasperReports in Verbindung mit iReport
eine tolle Sache ist...
Naja. Ich gebe zu, daß mich die bloße Existenz von iReport zum Einsatz
von JasperReport angeregt hat. Schön ist was anderes. Ich finde schon
etliche Designentscheidungen bei JR - nun - ungewöhnlich bis
gewöhnungsbedürftig. Zig Methoden für den Export in Zig verschiedene
Dateiformen statt _eine_ für einen Stream. Soll der Nutzer der API die
Details doch selber erledigen - und wenn das Ergebnis in eine DB oder
per HTTP raus soll muß man keinen Umweg über Temp-Files gehen. So mal
als Beispiel. Oder das Kompilieren irgendwelcher generierten
Java-Klassen (auf Disk natürlich und um die dann .jasper zu nennen).
Also, äh, sowas läßt sich doch auch eleganter lösen!

Leider bieten die Alternativen alle kein für Endnutzer taugliches Tool
ala iReport oder man will sie aus anderen Gründen nicht einbinden (BIRT
z.B.). Also lebt man mit der Pest statt der Colera.


Nico
Christian-Josef Schrattenthaler
2008-04-26 08:56:54 UTC
Permalink
Hallo Nico!

Ich habe jetzt folgendes herausgefunden:

1. Ich kann per Optionen -> Klassenpfad einen zusätzlichen Ordner zum
Klassenpfad von iReport hinzufügen. Diesen kann ich dann unter
Optionen -> Pfad(e) zu Schriftarten aktivieren, und nach einem
Neustart sind dann diese Schriftarten in der Auswahl zur Verfügung.

2. Wenn es sich dabei aber um den ORdner C:\WINDOWS\Fonts handelt,
kommt es zu einem Fehler, und es werden nur die ersten paar
Schriftarten aus diesem ORdner zur Auswahl angezeigt. Der Fehler kommt
unter Windows XP und unter Windows Vista:
Ungültiger Zeichensatz in: C:\Windows\Fonts

3. Wenn ich nun direkt eine PDF-Datei erzeuge, funktioniert es
trotzdem einwandfrei. Der Font wird gefunden.

4. Wenn ich zuerst den JRViewer als Ausgabeeinheit verwende, und dann
dort per Spcierhn unter eine PDF-Datei erzeuge, kommt es zu einem
Fehler. Die Schriftart wird nicht gefunden.

5. Nehme ich den Ordner C:\WINDOWS\Fonts in den CLASSPATH von Windows
auf, dann funktioniert auch das Speichern unter aus dem JRViewer.

6. Eclipse verwendet immer eigene Classpath-Angaben, und ich kann
keinen externen Ordner zum Classpath hinzufügen. Erst im Run-Dialog
kann ich einen externen Ordner unter Classpath über Advanced
hinzufügen, und damit scheint meine Anwendung dann korrekt zu
funktionieren.

7. Jetzt habe ich mal Deinen Tipp mit FontFactory probiert, das hat
aber nicht funktioniert. Hier die Classe, welche den Report erzeugen
sollte:

***
package biz.soag.jr4ao.helpers;

import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.SQLException;
import java.util.HashMap;

import com.lowagie.text.FontFactory;

import net.sf.jasperreports.engine.JRException;
import net.sf.jasperreports.engine.JasperCompileManager;
import net.sf.jasperreports.engine.JasperFillManager;
import net.sf.jasperreports.engine.JasperPrint;
import net.sf.jasperreports.engine.JasperReport;
import net.sf.jasperreports.view.JasperViewer;

public class CreateReport {

public HashMap<String, String> cla;

public Connection conn;

public JasperReport jasperReport;

public JasperPrint jasperPrint;

public CreateReport(HashMap<String, String> cla) {
this.cla = cla;
createConnection();
generateReport();
showReport();
closeConnection();
}

private void createConnection() {
// Load ODBC driver.
try {
Class.forName("sun.jdbc.odbc.JdbcOdbcDriver");
} catch (ClassNotFoundException cnfe) {
cnfe.printStackTrace();
}

// Create connection.
try {
conn = DriverManager
.getConnection("jdbc:odbc:Driver={Omnis ODBC Driver};DataFilePath="
+
cla.get("df"));
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}

private void generateReport() {
//
FontFactory.registerDirectory("C:\\WINDOWS\\Fonts");

// Compile the given jrxml file.
try {
jasperReport =
JasperCompileManager.compileReport(cla.get("jf"));
} catch (JRException jre) {
jre.printStackTrace();
}

// Fill report with data.
try {
jasperPrint =
JasperFillManager.fillReport(jasperReport, cla, conn);
} catch (JRException jre) {
jre.printStackTrace();
}
}

private void showReport() {
// Show report.
JasperViewer.viewReport(jasperPrint, false);
}

private void closeConnection() {
// Close connection
try {
conn.close();
} catch (SQLException sqle) {
sqle.printStackTrace();
}
}

}
***

8. Ich bin zu dem Schluß gekommen, dass es am Besten wäre, wenn ich
einen Ordner fonts festlege, direkt im Ordner der Anwendung, und dort
müssen einfach die TTF-Dateien drin sein, die der Kunde verwenden
will. Dann tut man sich auch mit dem Sichern wesentlich einfacher. Ich
halte nichts von irgendwelchen Batch-Dateien, die hintenherum was
ändern, oder dass man den Kunden zwingt einen Classpath zu setzten.
Das macht alles nur unnötig Ärger. Einfach einen Doppelklick auf die
Jar-Datei, und dann muss alles rennen. Leider habe ich es bis jetzt
nicht geschafft, diesen Ordner im Programm festzulegen.

9. Alternativ funktioniert es einwandfrei, wenn man in der Jrxml-Datei
den kompletten Ordner angibt. Also anstatt arial.ttf nimmt man
C:\WINDOWS\Fonts\arial.ttf, und dann klappt es auch.

10. Du hast recht, alles ist bei JasperReports und iReport nicht gut,
aber es gab in aktuellen JavaMAgazin einen vergleich der 3 größten
OpenSource Varianten, und da hat JasperReports nicht so schlecht
abgeschnittten. Und wenn es darum geht unabhängig beim Kunden einen
grafischen Editor in deutscher Sprache zu installieren, hat iReport
meiner Meinung nach die Nase vorn. Zur Not kann man dann auch noch
selber per Editor Hand anlegen, und schon rennts. Meistens geht es eh
nur um ein bisschen Optik-Korrektur, die Scheiß-Arbeit der Erstellung
eines Reports bleibt eh an den Entwicklern hängen.

11. Vor lauter Testen ist die Qualität meines Codes auch schlecht
geworden, ich werde mich jetzt mal darum kümmern. Vielleicht findet
sich zwischenzeitlich ja eine Lösung für die Angabe eines
Font-Ordners.

Danke für Deine vielen Hinweise,
Christian.
Christian-Josef Schrattenthaler
2008-04-26 09:57:54 UTC
Permalink
Hallo!

Habe es jetzt so gelöst, dass es immer einen Ordner fonts im Ordner
meiner Anwendung gibt. Externe TTF-Dateien müssen in diesem ORdner
abgelegt werden.

Die Anwendung wird als Jar-Datei geliefert, und da musste nur der
Class-Path-Eintrag der MANIFEST.MF um ./fonts/ erweitert werden.

Die Anwendung wird mit Eclipse entwickelt, und damit darin die Test
funktionieren, muss der Ordner fonts über 'Build Path' -> 'Use as
Source Folder' zum Build-PAth hinzugefügt werden.

Habe es jetzt ausführlich getestet, und es funktioniert - zumindest
für mich - perfekt.

Danke für die Hilfe,
Christian.

Loading...