如何使用Java

时间:2017-08-03 21:18:21

标签: java exception printing document raw-data

我正在尝试创建一个简单的程序,将字符串发送到打印机进行打印。这就是我的程序:

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(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),但您似乎需要添加一种风味。

- 更换打印机,因为我试图打电话的原始打印机是贴标打印机,但这没有什么区别。

知道我在这里做错了什么吗?我该怎么做才能修复此代码并将其打印出来?

更新

我得到了(有点)工作。这就是我到目前为止所做的:

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

我现在唯一的打嗝是除非其他被发送到打印机,否则实际上打印。暂时离开这里作为参考。

1 个答案:

答案 0 :(得分:6)

异常消息非常有用,可以帮助您找到解决方案。

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

by:

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

这对应于上一输出中支持的最后一种风格:

  

应用:应用/八位字节流: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);