簡體   English   中英

如何使用Java將原始數據發送到打印機

[英]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:數據不是聲明的類型。

DocFlavorINPUT_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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM