2017-08-03 5 views
6

Ich versuche, ein einfaches Programm zu erstellen, das eine Zeichenfolge an einen Drucker zum Drucken sendet. Dies ist, was mein Programm wie folgt aussieht:So senden Sie Rohdaten an den Drucker mit Java

import javax.print.Doc; 
import javax.print.DocFlavor; 
import javax.print.DocPrintJob; 
import javax.print.PrintException; 
import javax.print.PrintService; 
import javax.print.PrintServiceLookup; 
import javax.print.SimpleDoc; 

public class PrinterTest { 
    public static void main (String [] args) throws PrintException { 
    DocPrintJob job = null; 
    PrintService[] printServices = 
    PrintServiceLookup.lookupPrintServices(null, null); 
    System.out.println("Number of print services: " + printServices.length); 
    for (PrintService printer : printServices) { 
     System.out.println("Printer: " + printer.getName()); 
     if (printer.getName().contains("ZM400")) { 
      String hello = "Hello"; 
      DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN; 
      Doc doc = new SimpleDoc(hello, flavor, null); 
      job = printer.createPrintJob(); 
      job.print(doc, null); 
     } 
    } 
    } 
} 

ich dies als eine JAR-Datei exportieren und auf der Kommandozeile (Windows) laufen mit:

java -jar PrinterTest.jar 

Das Programm läuft und startet Schleife durch alle die installierten Drucker auf dem Computer. Aber wenn es um den Drucker bekommt ich suche, erhalte ich dann folgende Fehlermeldung:

Exception in thread "main" sun.print.PrintJobFlavorException: invalid flavor 
    at sun.print.Win32PrintJob.print(Unknown Source) 
    at PrinterTest.main(PrinterTest.java:21) 

Nicht wirklich sicher, was ich falsch hier zu tun, wie der Drucker, die ich gesucht habe für sich in der Tat zeigen .

den folgenden Link als Referenz -Mit: http://docs.oracle.com/javase/7/docs/technotes/guides/jps/spec/jpsOverview.fm4.html

-Tried DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN-DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE zu ändern, aber ich habe den Fehler IllegalArgumentException: data is not of declared type.

-Tried Änderung Doc doc = new SimpleDoc(hello, flavor, null) zu Doc doc = new SimpleDoc(hello, null, null), aber es scheint, als ob Sie einen Geschmack dort hinzufügen müssen.

- Ich habe versucht, den Drucker zu wechseln, da der ursprüngliche Drucker, den ich anrufen wollte, ein Etikettendrucker war, aber das machte keinen Unterschied.

Irgendeine Idee, was ich hier falsch mache? Was kann ich tun, um diesen Code zu reparieren und zu drucken?

UPDATE

ich das (etwas) Arbeit bekam. Das ist, was ich habe, so weit:

import java.io.BufferedReader; 
import java.io.ByteArrayInputStream; 
import java.io.IOException; 
import java.io.InputStream; 
import java.io.InputStreamReader; 
import javax.print.Doc; 
import javax.print.DocFlavor; 
import javax.print.DocPrintJob; 
import javax.print.PrintException; 
import javax.print.PrintService; 
import javax.print.PrintServiceLookup; 
import javax.print.SimpleDoc; 

public class PrinterTest { 
    public static void main (String [] args) throws PrintException, IOException { 
    BufferedReader bufferedReader = new BufferedReader(new InputStreamReader(System.in)); 
    System.out.print("Enter the name of the printer: "); 
    String printerName = bufferedReader.readLine(); 
    System.out.print("Enter a short message of what you would like to print here: "); 
    String printerMessage = "PRINTER MESSAGE: " + bufferedReader.readLine(); 
    boolean printerCheck = false; 
    DocPrintJob job = null; 
    PrintService[] printServices = PrintServiceLookup.lookupPrintServices(null, null); 
    System.out.println("Number of print services: " + printServices.length); 
    for (PrintService printer : printServices) { 
     System.out.println("Printer: " + printer.getName()); 
     if (printer.getName().contains(printerName)) { 
      InputStream inputStream = new ByteArrayInputStream(printerMessage.getBytes()); 
      DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; 
      Doc doc = new SimpleDoc(inputStream, flavor, null); 
      job = printer.createPrintJob(); 
      job.print(doc, null); 
      printerCheck = true; 
     } 
    } 
    if (printerCheck == false) { 
     System.out.println("The printer you were searching for could not be found."); 
    } 
    } 
} 

Was ich den String in einen Eingangsstrom gelegt hat, und änderte DocFlavor.STRING.TEXT_PLAIN-DocFlavor.INPUT_STREAM.AUTOSENSE.

Mein einziger Schluckauf ist jetzt, dass nichts eigentlich druckt, es sei denn etwas anderes an den Drucker gesendet wird. Lassen Sie dies hier für jetzt als Referenz.

+1

Weg zurück in den dunklen Zeiten, einen Drucker die letzte Seite zu blättern, mußte man es einen ASCII-Form-Feed Byte senden '0xC' (erzeugt auf einem DOS-Terminal durch Eingabe von Control-L und normalerweise repräsentiert durch '^ L'). Wenn Ihr Drucker einzelne Blätter auswirft, anstatt einen ungebrochenen Strom von grünen Balken zu falten, ist dieses Wissen wahrscheinlich nicht hilfreich ... es sei denn, der Drucker wurde so entwickelt, dass er bis zu seriellen Punktmatrix-Druckern abwärtskompatibel ist . (Ich würde das geradezu charmant finden.) –

Antwort

4

Die Ausnahmemeldungen sind sehr hilfreich und sollten Ihnen helfen, eine Lösung zu finden.

1) Zuerst wird das Aroma nicht vom Drucker unterstützt:

DocFlavor.STRING.TEXT_PLAIN; 

Diese Ausnahme heißt es:

Exception in thread "main" sun.print.PrintJobFlavorException: invalid flavor

Wenn Sie in den Quellcode dieser konstanten Wert anschaut, kann sehen, dass es wie folgt erklärt wird:

public static final STRING TEXT_PLAIN = 
    new STRING ("text/plain; charset=utf-16"); 

Also, das erste, was Sie sh Überprüfen Sie, welche Varianten von Ihrem Drucker unterstützt werden.
es zu machen, den eigentlichen Code ändern:

if (printer.getName().contains("ZM400")) { 
    String hello = "Hello"; 
    DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN; 
    Doc doc = new SimpleDoc(hello, flavor, null); 
    job = printer.createPrintJob(); 
    job.print(doc, null); 
} 

von:

if (printer.getName().contains("ZM400")) { 
    Arrays.stream(printer.getSupportedDocFlavors()).forEach(f->System.out.println(f.getMediaType() + ":" + f.getMimeType() + ":" + f.getRepresentationClassName())); 
    String hello = "Hello"; 
    DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN; 
    Doc doc = new SimpleDoc(hello, flavor, null); 
    job = printer.createPrintJob(); 
    job.print(doc, null); 
} 

Mit meinem Drucker, es erzeugt die folgende Ausgabe:

image:image/gif:[B image:image/gif:java.io.InputStream

image:image/gif:java.net.URL image:image/jpeg:[B

image:image/jpeg:java.io.InputStream image:image/jpeg:java.net.URL

image:image/png:[B image:image/png:java.io.InputStream

image:image/png:java.net.URL

application:application/x-java-jvm-local-objectref:java.awt.print.Pageable

application:application/x-java-jvm-local-objectref:java.awt.print.Printable

application:application/octet-stream:[B

application:application/octet-stream:java.net.URL

application:application/octet-stream:java.io.InputStream

Sie können die meinen Drucker bemerken unterstützt die "text/plain; charset=utf-16" Geschmacksrichtung nicht.

2) Wenn Sie den Geschmack zu DocFlavor.INPUT_STREAM.AUTOSENSE ändern, haben Sie nicht mehr die Ausnahme, die mit fehlender Unterstützung für die DocFlavor zusammenhängt.
Dies bedeutet, dass DocFlavor.INPUT_STREAM.AUTOSENSE von Ihrem Drucker unterstützt wird.
Aber Sie stoßen ein anderes Problem als die Daten zum Drucken nicht deklarierten Typ zu DocFlavor.INPUT_STREAM.AUTOSENSE zugeordnet überein:

IllegalArgumentException: data is not of declared type.

In DocFlavor, die INPUT_STREAM.AUTOSENSE konstant auf diese Weise deklariert ist:

public static final INPUT_STREAM AUTOSENSE = 
     new INPUT_STREAM ("application/octet-stream"); 

Diese entspricht dem zuletzt unterstützten Geschmack in der vorherigen Ausgabe:

application:application/octet-stream:java.io.InputStream

An d das Problem gibt es:

String hello = "Hello";  
... 
Doc doc = new SimpleDoc(hello, flavor, null); 

Sie haben keine InputStream passieren, aber ein String.

Sie können zum Beispiel eine InputStream auf diese Weise bieten:

String hello = "Hello";  
DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE; 
Doc doc = new SimpleDoc(new ByteArrayInputStream(hello.getBytes()), 
         flavor, null); 

Oder Sie könnten diesen Geschmack auch verwenden:

application:application/octet-stream:[B

wie Sie keine InputStream aber eine String als Eingabe haben:

Hier ist die Flavor-Konstante zu verwenden:

DocFlavor.BYTE_ARRAY.AUTOSENSE 

Sie auch auf diese Weise nutzen könnten:

String hello = "Hello";  
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; 
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null); 
Verwandte Themen