2017-08-03 179 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); 
相关问题