[英]How to send raw data to printer with 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
- 將DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN
更改為DocFlavor 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_PLAIN
更改為DocFlavor.INPUT_STREAM.AUTOSENSE
。
is sent to the printer. 我唯一的打嗝,現在是沒有什么實際打印,除非被發送到打印機。 現在留待這里作為參考。
異常消息非常有用,可以幫助您找到解決方案。
1)首先,您的打印機不支持此風格:
DocFlavor.STRING.TEXT_PLAIN;
這個例外說:
線程“main”中的異常sun.print.PrintJobFlavorException:無效的味道
如果查看此常量值的源代碼,可以看到它被聲明為:
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
圖像:圖像/ PNG:java.net.URL中
應用:應用程序/ x-Java的JVM,局部objectref:java.awt.print.Pageable
應用:應用程序/ x-Java的JVM,局部objectref:java.awt.print.Printable
應用:應用/八位字節流:[B
應用:應用/八位字節流:java.net.URL中
應用:應用/八位字節流:java.io.InputStream中
你可能會注意到我的打印機不支持"text/plain; charset=utf-16"
味道。
2)通過將味道更改為DocFlavor.INPUT_STREAM.AUTOSENSE
,您不再有與缺少對DocFlavor
支持相關的異常。
因此,這意味着您的打印機支持DocFlavor.INPUT_STREAM.AUTOSENSE
。
但是您遇到另一個問題,因為要打印的數據與DocFlavor.INPUT_STREAM.AUTOSENSE
關聯的聲明類型不匹配:
IllegalArgumentException:數據不是聲明的類型。
在DocFlavor
, INPUT_STREAM.AUTOSENSE
常量以這種方式聲明:
public static final INPUT_STREAM AUTOSENSE =
new INPUT_STREAM ("application/octet-stream");
這對應於上一個輸出中最后支持的flavor:
應用:應用/八位字節流:java.io.InputStream中
問題出在那里:
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);
或者你也可以使用這種味道:
應用:應用/八位字節流:[B
因為你沒有InputStream
而是String
作為輸入:
這是使用的風味常量:
DocFlavor.BYTE_ARRAY.AUTOSENSE
您也可以這樣使用它:
String hello = "Hello";
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null);
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.