PDF via Java ausdrucken lassen

jeipack

Erfahrenes Mitglied
#1
Hi Forum
hoffe ihr hattet alle nen guten Start in die Woche.
Ich arbeite hier viel mit JasperReports. Das Problem dabei ist, dass neuere Versionen von JasperReports sehr grosse Grafiken (Diagramme) erstellen und wenn ein Report gedruckt werden soll schnell mal ein 500MB Druckjob erstellt wird, was eindeutig zu viel ist.
Nun dacht ich mir, dass ich einen Umweg über ein PDF File mache und dies dann ausdrucke.
Dies funktioniert grundsätzlich auch mit der Bibliothek jdic:
Java:
//-------- probieren direkt ein pdf zu erstellen -------------
                    JRSaveContributor saveContrib=null;
                    try
                  {
                  Class saveContribClass = JRClassLoader.loadClassForName("net.sf.jasperreports.view.save.JRPdfSaveContributor");
                  Method method = saveContribClass.getMethod("getInstance", (Class[])null);
                  saveContrib = (JRSaveContributor)method.invoke(null, (Object[])null);

                  }
                  catch (Exception e)
                  {
                      System.out.println("Fehler beim Erstellen des saveContrib Objekt:\n\r"+e);
                  }
                  File pdffile=null;
                  try {

                  pdffile = new File("c:\\temp.pdf");
//                  pdffile.createNewFile();
                  System.out.println("File kann geschrieben werden: "+pdffile.canWrite());

                  saveContrib.save(jp, pdffile);

                  } catch (Exception ex) {
                      System.out.println("Fehler beim schreiben des pdf Files:\n\r"+ex);
                  }

//und nun noch das pdffile ausdrucken

if(Desktop.isPrintable(pdffile)) {
                      try {
                          Desktop.print(pdffile);
                      } catch (Exception ex) {
                          System.out.println("Fehler beim drucken des dpf Files:\n\r"+ex);
                      }
                  }

Das Problem dabei ist nun, dass man an den Acrobat gebunden ist, aber vor allem dass man nur auf den standard Drucker ausdrucken kann.

Gibt es keine Möglichkeit ein PDF direkt mit Java zu drucken, ohne ein externes Programm zu verwenden?
Das ganze bräuchte ich für Windows. Plattformunabhängig wär natürlich noch besser =)

Vielen Dank für eure Hilfe
jeipack
 

KlaDi

Erfahrenes Mitglied
#2
Hallo,

probiers mal damit:

Code:
String ausdruck = "C:\\meinPDF.pdf";
File ausdruckfile = new File(ausdruck);
    	if(Desktop.isDesktopSupported()) {
    		Desktop dt = Desktop.getDesktop();
    		try {
				dt.print(ausdruckfile);
			} catch (IOException e) {
				e.printStackTrace();
			}
    	}
Hab ich nach langem suchen unter gefunden. Ich glaube dazu muss noch die java.awt.Desktop importiert werden.

Gruß KlaDi.
 

jeipack

Erfahrenes Mitglied
#3
Bekommst du damit ein Dialog bei dem du den Drucker auswählen kannst?
Ich kanns bei mir nicht ausprobieren, da ich unter java.awt keinen Desktop habe.
Der Desktop der bei mir drin ist, ist: org.jdesktop.jdic.desktop.Desktop
Und meine JDK Version ist 1.5 (JBuilder2006)

Gruss und schonmal Danke.
 

KlaDi

Erfahrenes Mitglied
#4
Also wenn ich mich recht erinnere, ging da kein Dialogfeld auf, sonder die Datei wurde direkt an den Standarddrucker geschickt.

Gruß KlaDi.
 

jeipack

Erfahrenes Mitglied
#5
KlaDi hat gesagt.:
Also wenn ich mich recht erinnere, ging da kein Dialogfeld auf, sonder die Datei wurde direkt an den Standarddrucker geschickt.
Ja.. genau das habe ich ja schon. Den Drucker muss ich aber zwingend auswählen können :/

Gruss
 

jeipack

Erfahrenes Mitglied
#6
Hey, oder kennt vielleicht jemand eine andere Möglichkeit den DruckJob der JasperReports Dateien zu verkleinern? Ihrgendwie muss ich das nämlich hin bekommen :/

Gruss und vielen Dank
jeipack
 
#7
Hi,

hier mal eine Lösung mit JPedal.

Code:
/*
 * Main.java
 * Created on 22. Februar 2007, 09:50
 *
 */

package pdfdrucker;

import java.awt.print.PageFormat;
import java.awt.print.PrinterJob;
import java.util.Iterator;
import javax.print.DocFlavor;
import javax.print.PrintService;
import javax.print.PrintServiceLookup;
import javax.print.ServiceUI;
import javax.print.attribute.HashPrintRequestAttributeSet;
import javax.print.attribute.PrintRequestAttributeSet;
import javax.print.attribute.standard.MediaSizeName;
import javax.print.attribute.standard.NumberUp;
import javax.print.attribute.standard.Sides;
import org.jpedal.PdfDecoder;
import org.jpedal.io.PdfReader;

/**
 *
 * @author THEOBALD
 */

import java.awt.print.*;
import java.io.File;
import java.io.PrintStream;
import java.lang.reflect.Array;
import java.util.Hashtable;
import javax.print.PrintService;
import javax.print.attribute.*;
import org.jpedal.PdfDecoder;
import org.jpedal.utils.LogWriter;

public class PdfPrint {
    
    private static boolean debugCode = true;
    private final String separator = System.getProperty("file.separator");
    private PdfDecoder decode_pdf;
    private int maxCopies;
    private int copiesToPrint;
    private int pageCount;

    
    public PdfPrint(String s) {
        decode_pdf = null;
        maxCopies = 5;
        copiesToPrint = 1;
        
        if(s.toLowerCase().endsWith(".pdf")) {
            decodeAndPrintFile(s);
        } else {
            String as[] = null;
            Object obj = null;
            if(!s.endsWith(separator))
                s = s + separator;
            try {
                File file = new File(s);
                if(!file.isDirectory())
                    System.err.println(s + " ist kein Verzeichnis. Exit");
                as = file.list();
            } catch(Exception exception) {
                LogWriter.writeLog("Exception beim öffnen der Datei " + exception.getMessage());
            }
            long l = as.length;
            for(int i = 0; (long)i < l; i++){
                if(as[i].toLowerCase().endsWith(".pdf")) {
                logMessage(s + as[i]);
                decodeAndPrintFile(s + as[i]);
                }
            }
        }
    }
    
    private void decodeAndPrintFile(String s) {
        try {
            logMessage("Öffne Datei :" + s + " zum drucken.");
            decode_pdf = new PdfDecoder(true);
            decode_pdf.openPdfFile(s);
            pageCount = decode_pdf.getPageCount();
        } catch(Exception exception) {
            reportError("Exception " + exception );
        }
        if(decode_pdf.isEncrypted() && !decode_pdf.isExtractionAllowed())
            logMessage("Encrypted");
        else
            printAllCopies();
        decode_pdf.closePdfFile();
    }
    
    private final void printAllCopies() {
        for(int i = 0; i < copiesToPrint; i++) {
            logMessage("========================");
            logMessage("\nDrucke Kopie " + (i + 1));
            logMessage("========================");
            printPages();
        }
        
    }
    
    private void printPages() {

        try {
            
            PrinterJob printerjob = PrinterJob.getPrinterJob();
            //Öffnet den Printdialog
            printerjob.printDialog();
            
            PageFormat pageformat = printerjob.defaultPage();

            Paper paper = new Paper();
            paper.setSize(595D, 842D);
            paper.setImageableArea(0.0D, 0.0D, 595D, 842D);
            pageformat.setPaper(paper);
            printerjob.setCopies(1);
            
            
            decode_pdf.setPageFormat(pageformat);
            decode_pdf.setPrintAutoRotateAndCenter(true);
            decode_pdf.setPagePrintRange(1, 2);
            
            printerjob.setPageable(decode_pdf);
            
        } catch(Exception exception) {
            LogWriter.writeLog("Exception " + exception + "beim drucken");
        } catch(Error error) {
            LogWriter.writeLog("Error " + error + " beim drucken");
        }
    }
    
    private static void logMessage(String s) {
        if(debugCode) {
            System.out.println(s);
            LogWriter.writeLog(s);
        }
    }
    
    private void reportError(String s) {
        System.err.println(s);
        LogWriter.writeLog(s);
    }
    
    public static void main(String args[]) {
        
        String s = "C:\\test.pdf";
        logMessage("Datei :" + s);
        File file = new File(s);
        if(!file.exists())
            logMessage("Datei " + s + " nicht gefunden");
        PdfPrint print = new PdfPrint(s);
 
    }
}
 

jeipack

Erfahrenes Mitglied
#8
Hey Oliver
Vielen Dank für deine Mühe. Leider darf ich die GPL nicht benutzen und JPedal steht unter GPL oder CommercialLicence und kostet dann ca. 1000Euro pro benutze Version (was ich auch nicht machen kann). :(
Das einzige was ich benutzen darf ist LGPL.

Ich probierte es auch nocht mit javax.print.*. Allerdings muss der Drucker dann den DocFlavor INPUT_STREAM.PDF unterstüzen, und das tun lange nicht alle Drucker.

Gruss
jeipack
 

jeipack

Erfahrenes Mitglied
#10
Wow genial!

und das mit so einem kleinen Code:
Java:
public void pdfBoxTest() {
    PDDocument doc=null;
    try {
        doc = PDDocument.load("C:\\temp.pdf");
        doc.print();
    } catch (Exception ex) {
        ex.printStackTrace();
    } finally {
        if (doc != null) {
            try {
                doc.close();
            } catch (IOException ex1) {
                ex1.printStackTrace();
            }
        }
    }
}
Vielen Dank
 

urkus

Grünschnabel
#12
Hallo zusammen,

auch ich habe dieses Problem, daß ich PDFs im Hintergrund ausdrucken muß.
Die angegebene Lösung mit PDFBox ist an sich ziemlich gut.

Dabei gibt es leider nur einen Schönheitsfehler.... Sofern es sich um Dokumente mit Formularfeldern werden diese beim Drucken fehlinterpretiert, sprich die Schriftarten sind vollkommen anders. Ich habe auch einen Barcode, der dann überhaupt nicht gedruckt wird.
Das ist zumindest die Erfahrung, die ich gemacht habe.

Ein Kollege gab mir nun einen guten Tipp: http://www.esnips.com/_t_/pdfp
Es gibt zwei Versionen: Die eine ist für Version 8 und die andere für den Rest.
(Voraussetzung ist natürlich, daß Adobe installiert sein muß.)
Bis dato funktioniert es einwandfrei!

Übergabe dann wie üblich per Runtime.exec....

Vielleicht hilft es dem einen oder anderen weiter, der dieselben Probleme hat(te) wie ich...
 

jeipack

Erfahrenes Mitglied
#13
Hi urkus
Ich musste auch schon Feststellen das PDFBox nicht ideal ist (Bilder werden falsch interpretiert).

Im Moment mach ichs auch via Runtime.exec
und dann einfach "acrobat.exe /p pdffile.pdf" (wo die acrobat.exe liegt, finde ich via swt raus -> Thread)
 
J

JTeberion

#14
Ich wollte nur sagen das ihr mir den Tag gerettet habt.

das über pdf box ist die aller beste und kürzeste lösung die ich bisher gefundne habe alles andere ist echt großer schwachsinn!

danke
 
#15
Hallo Zusammen,

ich muss das Thema nochmal aufgreifen, da ich auch vor dem Problem stehe PDF Dateien ausdrucken zu wollen.
Habe dazu PDFBox eingebunden und folgenden Code geschrieben:
Java:
File datei = new File("C:\\161413070_00-76-150-1803_FIP_170109.pdf");
        if(datei.exists())
        {
            try(PDDocument doc = PDDocument.load(datei)) {
                PrinterJob job = PrinterJob.getPrinterJob();
                job.setPageable(new PDFPageable(doc));
                if(job.printDialog())
                {
                    job.print();
                }

            }catch(InvalidPasswordException ivpwe)
            {
                Logger.getLogger(WinScanJ.class.getName()).log(Level.SEVERE, null, ivpwe);
            }
            catch(IOException | PrinterException ioe)
            {
                Logger.getLogger(WinScanJ.class.getName()).log(Level.SEVERE, null, ioe);
            }
        }
Das läuft auch ohne Fehler durch und Windows scheint auch etwas an den Drucker zu senden, jedoch spuckt der Drucker nichts aus.
Ich vermute, dass evtl. ein leerer Druckauftrag raus geschickt wird, ich verstehe aber nicht warum. Hat jemand mit PDFBox Erfahrungen oder kann sich erklären, warum es bei mir nicht funktioniert?
Das PDF File ist definitiv nicht leer und Drucker sind auch installiert.