2017-08-03 177 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.STRING.TEXT_PLAINDocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE,但我得到的錯誤IllegalArgumentException: data is not of declared type

- 已更改Doc doc = new SimpleDoc(hello, flavor, null)Doc doc = new SimpleDoc(hello, null, null),但似乎您需要在那裏添加一種口味。

- 更換打印機,因爲我試圖打電話的原始打印機是標籤打印機,但這並沒有什麼區別。

任何想法我在這裏做錯了嗎?我能做些什麼來修復這些代碼並使其打印?

UPDATE

我這來(有點)工作。這是我到目前爲止有:

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

我所做的就是把字符串轉換爲輸入流,並改變DocFlavor.STRING.TEXT_PLAINDocFlavor.INPUT_STREAM.AUTOSENSE

我唯一的打嗝,現在是沒有什麼實際打印除非別的被髮送到打印機。現在留在這裏供參考。

+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聲明類型:

IllegalArgumentException: data is not of declared type.

DocFlavor,該INPUT_STREAM.AUTOSENSE常量聲明中這樣說:

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

這對應於前一次輸出中最後一次支持的風格:

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

An d問題有:

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

你沒有傳遞InputStreamString

例如,您可以提供這樣一個InputStream

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

或者你也可以使用這個味道:因爲你沒有一個InputStreamString作爲輸入

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); 
相關問題