Marc Reichelt: PDF-Dateien aus Java drucken

Hallo an alle,

ich habe momentan bei einem Bekannten einen kleinen Nebenjob angenommen.
Dieser arbeitet derzeit an einem Programm, das bestimmte Informationen nimmt und auswertet (mit Graphics2D gezeichnete Diagramme, Tabellen mit JTable, Text).

Ich habe nun die Aufgabe bekommen, den Export dieser Daten zu erledigen. Gefordert sind die Ausgabe von PDF-Dateien sowie die direkte Ausgabe auf einen Drucker.
Das Erzeugen von PDF-Dateien schaffe ich soweit bestimmt. Derzeit behelfe ich mich für eine kurzfristige Lösung mittels iText, später würde ich die Dokumente aber gerne über den "Umweg" OpenDocument-Format erstellen, da die PDF-Dateien hier viel einfacher und besser erzeugt werden können.

Nun zu meinem Problem: Die Inhalte (am Besten die PDF-Dateien) sollen direkt vom Java-Programm aus gedruckt werden können (kein Umweg über Adobe Reader).
Und ich finde einfach keine Möglichkeit, um PDF-Dateien mit Java auszudrucken. Eine GPL-Lösung kann ich leider nicht annehmen, da das Projekt Closed Source ist - und ich darauf auch keinen Einfluss habe. Ebenso schlecht sind Kosten, da das Projekt ohnehin viel davon verschlingt.
LGPL wäre also optimal.

Kennt jemand von euch eine solche Möglichkeit?

Ich würde am liebsten OpenOffice dazu verwenden, das glücklicherweise noch dazu unter der LGPL steht, und genau diese Funktionalitäten bietet, die ich haben möchte - allein die Komplexität macht mir Sorgen.

Oder gibt es eine andere, schnellere und plattformunabhängige Möglichkeit?

Und noch ganz nebenbei: Gibt es eine freie Möglichkeit, ein Graphics2D-Objekt als Bild (vorzugsweise PNG) zu exportieren?

Grüße & vielen Dank im Voraus

Marc Reichelt || http://www.marcreichelt.de/

--
Linux is like a wigwam - no windows, no gates and an Apache inside!
Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
http://emmanuel.dammerer.at/selfcode.html
  1. Hallo Marc,

    Mit FOP solltest Du sowohl PDF erzeugen als auch per Java Printing API drucken können.
    FOP ist eine implementierung von XSL FO. Ich hab' das selbst noch nicht verwendet, aber wenn Du keine zu großen Ansprüche an die Layoutmöglichkeiten hast, ist das eine gute Lösung.

    Grüße

    Daniel

    1. Hallo Daniel,

      Mit FOP solltest Du sowohl PDF erzeugen als auch per Java Printing API drucken können.
      FOP ist eine implementierung von XSL FO. Ich hab' das selbst noch nicht verwendet, aber wenn Du keine zu großen Ansprüche an die Layoutmöglichkeiten hast, ist das eine gute Lösung.

      Sowie ich das sehe, unterstützt es aber auch nicht das Graphics2D-Objekt. Wenn ich eine Möglichkeit finde, ein Graphics2D-Objekt in einer PNG-Datei abzuspeichern, wird deine genannte Lösung interessant. Ich werde sie mir aber auf jeden Fall auf meinen Notizzettel schreiben. :-)

      Ich suche mich gerade ein wenig durch, und so wie es aussieht könnten JIMI und JAI für mich interessant werden.

      Grüße

      Marc Reichelt || http://www.marcreichelt.de/

      --
      Linux is like a wigwam - no windows, no gates and an Apache inside!
      Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
      http://emmanuel.dammerer.at/selfcode.html
      1. Hallo.

        Sowie ich das sehe, unterstützt es aber auch nicht das Graphics2D-Objekt. Wenn ich eine Möglichkeit finde, ein Graphics2D-Objekt in einer PNG-Datei abzuspeichern, wird deine genannte Lösung interessant.

        Ich bin kein Experte auf dem Gebiet der Java-Grafikfuktionen, aber so wie ich das sehe, gibt es keine Möglichkeit, nur aus dem Graphics(2D)-Objekt die Imagedaten zu gewinnen.

        Anders sieht es jedoch aus, wenn du Zugriff auf die Komponente, in der sich alle grafischen Ausgaben abspielen, hast (kann z.B. der oberste Container sein). Ich würde den dann manuell mit Doppelpufferung versehen und das Offscreen-Image wie benötig weiterverarbeiten, z.B. mit den Klassen aus javax.imageio wie ImageIO.

        Gruß
         Christoph

        1. Hallo Christoph,

          Ich bin kein Experte auf dem Gebiet der Java-Grafikfuktionen, aber so wie ich das sehe, gibt es keine Möglichkeit, nur aus dem Graphics(2D)-Objekt die Imagedaten zu gewinnen.

          Richtig, das musste ich leider auch feststellen.

          Anders sieht es jedoch aus, wenn du Zugriff auf die Komponente, in der sich alle grafischen Ausgaben abspielen, hast (kann z.B. der oberste Container sein). Ich würde den dann manuell mit Doppelpufferung versehen und das Offscreen-Image wie benötig weiterverarbeiten, z.B. mit den Klassen aus javax.imageio wie ImageIO.

          So ähnlich habe ich es nun gemacht, Stichwort BufferedImage.
          Mit Hilfe der createGraphics()-Methode erzeugt man ein Graphics2D-Objekt.

          Über eine Schleife habe ich nun dafür gesorgt, dass die Zeichenmethoden zwei Mal ausgeführt werden: Einmal zum Zeichnen auf den Bildschirm, und ein Mal zum Erzeugen der PNG-Datei.

          Vielen Dank! Auch wenn ich bereits selbst auf die Lösung gekommen bin, aber du hast genau den richtigen Ansatz getroffen! :-)

          Grüße

          Marc Reichelt || http://www.marcreichelt.de/

          --
          Linux is like a wigwam - no windows, no gates and an Apache inside!
          Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
          http://emmanuel.dammerer.at/selfcode.html
          1. Hallo,

            Über eine Schleife habe ich nun dafür gesorgt, dass die Zeichenmethoden zwei Mal ausgeführt werden: Einmal zum Zeichnen auf den Bildschirm, und ein Mal zum Erzeugen der PNG-Datei.

            Du kannst das auch in einem Aufwasch machen, indem du in das BufferedImage
            reinschreibst und danach das BufferedImage über Graphics(2D).drawImage(...)
            ausgibst.

            Je nachdem wie aufwendig die Zeichenoperationen sind, wirst du damit
            erhebliche Rechenzeit sparen, weil alle Operationen nur einmal ausgeführt
            werden müssen. Und das BufferedImage mußt du ja ohnehin erzeugen...

            Gruß
            Slyh

            1. Hallo,

              Du kannst das auch in einem Aufwasch machen, indem du in das BufferedImage
              reinschreibst und danach das BufferedImage über Graphics(2D).drawImage(...)
              ausgibst.

              Was dann im Allgemeinen als Doppelpufferung bezeichnet wird ;)

              Gruß
               Christoph

            2. Hallo Slyh,

              Du kannst das auch in einem Aufwasch machen, indem du in das BufferedImage
              reinschreibst und danach das BufferedImage über Graphics(2D).drawImage(...)
              ausgibst.

              Je nachdem wie aufwendig die Zeichenoperationen sind, wirst du damit
              erhebliche Rechenzeit sparen, weil alle Operationen nur einmal ausgeführt
              werden müssen. Und das BufferedImage mußt du ja ohnehin erzeugen...

              Jepp, habe ich auch gleich ausgetestet - und es hat funktioniert. Dann habe ich es aber wieder rückgängig gemacht, da die Grafik auf dem Bildschirm einen grauen und die für den Drucker einen weißen Hintergrund hat.
              Mittlerweile kann ich auch endlich dank FOP PDF- und PS-Dateien exportieren und die PS-Dateien dann direkt mit Java an den Drucker senden. *freu*

              Grüße

              Marc Reichelt || http://www.marcreichelt.de/

              --
              Linux is like a wigwam - no windows, no gates and an Apache inside!
              Selfcode: ie:{ fl:| br:> va:} ls:< fo:} rl:( n4:( ss:) de:> js:| ch:? sh:| mo:) zu:)
              http://emmanuel.dammerer.at/selfcode.html