2017-08-03 31 views
6

Tôi đang cố gắng tạo một chương trình đơn giản gửi một chuỗi tới máy in để in. Đây là những gì chương trình của tôi trông giống như:Cách gửi dữ liệu thô đến máy in bằng 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); 
     } 
    } 
    } 
} 

tôi xuất này như một file jar và chạy nó trên dòng lệnh (Windows) sử dụng:

java -jar PrinterTest.jar 

Chương trình chạy, và bắt đầu vòng lặp qua tất cả các máy in đã cài đặt trên máy tính. Nhưng khi nó được cho máy in Tôi đang tìm kiếm, sau đó tôi nhận được lỗi sau:

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

Không thực sự chắc chắn những gì tôi đang làm sai ở đây, như các máy in mà tôi đang tìm kiếm không thực hiện .

-Sử dụng liên kết sau đây để tham khảo: http://docs.oracle.com/javase/7/docs/technotes/guides/jps/spec/jpsOverview.fm4.html

-Tried thay đổi DocFlavor flavor = DocFlavor.STRING.TEXT_PLAIN-DocFlavor flavor = DocFlavor.INPUT_STREAM.AUTOSENSE, nhưng tôi nhận được lỗi IllegalArgumentException: data is not of declared type.

Đã thay đổi Doc doc = new SimpleDoc(hello, flavor, null) thành Doc doc = new SimpleDoc(hello, null, null), nhưng có vẻ như bạn cần thêm hương vị ở đó.

-Thay đổi máy in, vì máy in gốc mà tôi đang cố gọi là máy in ghi nhãn, nhưng điều đó không tạo nên sự khác biệt.

Bất kỳ ý tưởng nào tôi đang làm sai ở đây? Tôi có thể làm gì để sửa mã này và in nó?

CẬP NHẬT

tôi nhận này để làm việc (phần nào). Đây là những gì tôi có cho đến nay:

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

Những gì tôi đã làm là đưa các chuỗi thành một dòng đầu vào, và thay đổi DocFlavor.STRING.TEXT_PLAIN-DocFlavor.INPUT_STREAM.AUTOSENSE.

Hiện nấc cục duy nhất của tôi bây giờ là không có gì thực sự in trừ khi một thứ khác được gửi tới máy in. Rời khỏi đây ngay bây giờ để tham khảo.

+1

Way trở lại trong thời đại đen tối, để có được một máy in để di chuyển trang cuối cùng ra, bạn phải gửi một byte ASCII dạng nguồn cấp dữ liệu '0xC' (được tạo trên thiết bị đầu cuối DOS bằng cách gõ Control-L, và thường được biểu diễn'^L'). Nếu máy in của bạn đẩy các tờ riêng lẻ thay vì phát ra một luồng giấy màu xanh lá cây không bị gián đoạn, kiến ​​thức này có thể không hữu ích ... trừ khi máy in được thiết kế tương thích ngược tất cả cách quay lại máy in nối tiếp ma trận chấm . (Tôi sẽ thấy điều đó thật quyến rũ.) –

Trả lời

4

Thông báo ngoại lệ khá hữu ích và sẽ giúp bạn tìm giải pháp.

1) Thứ nhất, hương vị này không được hỗ trợ bởi máy in của bạn:

DocFlavor.STRING.TEXT_PLAIN; 

ngoại lệ này cho biết:

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

Nếu bạn nhìn vào mã nguồn của giá trị không đổi này, bạn có thể thấy rằng nó được khai báo là:

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

Vì vậy, điều đầu tiên bạn sh hãy làm là kiểm tra những hương vị được hỗ trợ bởi máy in của bạn.
Để làm cho nó, thay đổi mã thực tế:

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

bởi:

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

Với máy in của tôi, nó tạo ra kết quả như sau:

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

Bạn có thể nhận thấy máy in của tôi không hỗ trợ các đặc điểm "text/plain; charset=utf-16".

2) Bằng cách thay đổi hương vị thành DocFlavor.INPUT_STREAM.AUTOSENSE, bạn không còn bất kỳ ngoại lệ nào liên quan đến việc thiếu hỗ trợ cho số DocFlavor.
Vì vậy, nó có nghĩa là DocFlavor.INPUT_STREAM.AUTOSENSE được hỗ trợ bởi máy in của bạn.
Nhưng bạn gặp phải một vấn đề khác như các dữ liệu để in không phù hợp với loại hình tuyên bố liên quan đến DocFlavor.INPUT_STREAM.AUTOSENSE:

IllegalArgumentException: data is not of declared type.

Trong DocFlavor, hằng INPUT_STREAM.AUTOSENSE được khai báo theo cách này:

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

này tương ứng với hương vị được hỗ trợ cuối cùng trong kết quả trước đó:

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

An d vấn đề là ở đó:

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

bạn không có vượt qua một InputStream nhưng một String.

Bạn có thể ví dụ như cung cấp một InputStream theo cách này:

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

Hoặc bạn cũng có thể sử dụng hương vị này:

application:application/octet-stream:[B

là bạn có không phải là một InputStream nhưng một String như là đầu vào:

Đây là hằng số hương vị cần sử dụng:

DocFlavor.BYTE_ARRAY.AUTOSENSE 

Bạn cũng có thể sử dụng nó theo cách này:

String hello = "Hello";  
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE; 
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null); 
Các vấn đề liên quan