如何使用 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
程序 运行s,并开始循环遍历计算机上所有已安装的打印机。但是当它到达我正在寻找的打印机时,我收到以下错误:
Exception in thread "main" sun.print.PrintJobFlavorException: invalid flavor
at sun.print.Win32PrintJob.print(Unknown Source)
at PrinterTest.main(PrinterTest.java:21)
不太确定我在这里做错了什么,因为我正在搜索的打印机确实出现了。
-使用以下link供参考: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)首先,您的打印机不支持这种风格:
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) 通过将 flavor 更改为 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
问题就在那里:
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);
或者你也可以使用这种口味:
application:application/octet-stream:[B
因为您输入的不是 InputStream
而是 String
:
这里是要使用的风味常量:
DocFlavor.BYTE_ARRAY.AUTOSENSE
你也可以这样使用:
String hello = "Hello";
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null);
我正在尝试创建一个简单的程序,将字符串发送到打印机进行打印。这是我的程序的样子:
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
程序 运行s,并开始循环遍历计算机上所有已安装的打印机。但是当它到达我正在寻找的打印机时,我收到以下错误:
Exception in thread "main" sun.print.PrintJobFlavorException: invalid flavor
at sun.print.Win32PrintJob.print(Unknown Source)
at PrinterTest.main(PrinterTest.java:21)
不太确定我在这里做错了什么,因为我正在搜索的打印机确实出现了。
-使用以下link供参考: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)首先,您的打印机不支持这种风格:
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) 通过将 flavor 更改为 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
问题就在那里:
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);
或者你也可以使用这种口味:
application:application/octet-stream:[B
因为您输入的不是 InputStream
而是 String
:
这里是要使用的风味常量:
DocFlavor.BYTE_ARRAY.AUTOSENSE
你也可以这样使用:
String hello = "Hello";
DocFlavor flavor = DocFlavor.BYTE_ARRAY.AUTOSENSE;
Doc doc = new SimpleDoc(hello.getBytes(), flavor, null);