2017-08-03 7 views
6

印刷する文字列をプリンタに送る簡単なプログラムを作成しようとしています。これは、私のプログラムがどのようなものか: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); 
     } 
    } 
    } 
} 

私はjarファイルとしてこれをエクスポートして、コマンドライン(Windowsの場合)使用した上で、それを実行します。

java -jar PrinterTest.jar 

プログラムが実行され、すべてをループを開始しますインストールされているプリンタをコンピュータにインストールします。それは私が探していますプリンタになった場合でも、私は、次のエラーを取得する:私が探していたプリンタが実際に表示されないように私は、ここで間違ってやって

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

本当にわかりません。 http://docs.oracle.com/javase/7/docs/technotes/guides/jps/spec/jpsOverview.fm4.html

-TriedがDocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSEからDocFlavor flavor = DocFlavor.STRING.TEXT_PLAINを変更するが、私はエラーを取得しIllegalArgumentException: data is not of declared type:参照のための次のリンクを-Using

- Doc doc = new SimpleDoc(hello, flavor, null)からDoc doc = new SimpleDoc(hello, null, null)に変更しましたが、そこにフレーバーを追加する必要があるようです。

- 私が電話しようとしていた元のプリンタはラベルプリンタでしたが、それは違いはありませんでした。

ここで間違っているのは何ですか?このコードを修正して印刷するにはどうすればよいですか?

UPDATE

私は(多少)の仕事にこれを得ました。私は、入力ストリームに文字列を入れて、DocFlavor.INPUT_STREAM.AUTOSENSEDocFlavor.STRING.TEXT_PLAINを変更してやった

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."); 
    } 
    } 
} 

:これは私がこれまで持っているものです。

実際にが印刷されるのは、以外の何かがプリンタに送信されない限りです。これをここに残して参考にしてください。

+1

ウェイバック暗黒時代に、最後のページをスクロールするプリンタを得るために、あなたはそれをASCIIのフォームフィードのバイトを送信する必要がありました'0xC'(Control-Lと打ち込むことによってDOS端末で生成され、通常は'^L 'で表されます)。プリンタがグリーンバーの折りたたみ用紙の連続したストリームを出力するのではなく、個々のシートを取り出す場合、この知識は役に立たないでしょう...プリンタがドットマトリックスシリアルプリンタに戻って後方互換性があるように設計されていない限り。 (私はそれはまったく魅力的であることがわかります。) –

答えて

4

例外メッセージはむしろ役立ち、解決策を見つけるのに役立ちます。

1)まず、この味は、お使いのプリンタでサポートされていません。

DocFlavor.STRING.TEXT_PLAIN; 

この例外は、それを言う:

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

あなたはこの定数値のソースコードを見ると、あなたは

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

だから、最初に書いたことが分かりますあなたのプリンタでどのフレーバーがサポートされているかチェックしています。
実際のコードに変更、それをレンダリングする:によって

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); 
} 

を:私のプリンタで

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); 
} 

、それは次の出力を生成します。

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

あなたは私のプリンタに気づくことフレーバーも "text/plain; charset=utf-16"のいずれかをサポートしていません。

2)フレーバーをDocFlavor.INPUT_STREAM.AUTOSENSEに変更すると、DocFlavorのサポートの欠落に関する例外はなくなりました。
したがって、DocFlavor.INPUT_STREAM.AUTOSENSEがプリンタでサポートされていることを意味します。
しかし、あなたは、印刷にデータがDocFlavor.INPUT_STREAM.AUTOSENSEに関連する宣言された型に一致していないとして、別の問題が発生します。DocFlavor

IllegalArgumentException: data is not of declared type.

INPUT_STREAM.AUTOSENSE定数がこのように宣言されています。

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

この以前の出力で最後にサポートされたフレーバに対応します。

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

D問題があります:

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

あなたはInputStreamが、Stringを通過していません。

あなたは、例えば、このようにInputStreamを提供することができます。

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

それとも、この味使用することができます:あなたが入力としてInputStreamが、Stringを持っていないよう

application:application/octet-stream:[B

を:

ここに使用するフレーバー定数は次のとおりです。

DocFlavor.BYTE_ARRAY.AUTOSENSE 

ます。また、この方法でそれを使用することもできます

String hello = "Hello";  
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; 
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null); 
関連する問題