Как отправлять необработанные данные на принтер с 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) to 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 to DocFlavor.INPUT_STREAM.AUTOSENSE.

моя единственная икота сейчас-это ничего на самом деле печать, если что-то другое отправляется на принтер. Оставляю это здесь для справки.

1 ответов


сообщения об исключениях довольно полезны и должны помочь вам найти решение.

1) Во-первых, этот аромат не поддерживается вашим принтером :

 DocFlavor.STRING.TEXT_PLAIN;

это исключение говорит он :

исключение в потоке "main" sun.печать.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);
}

С моим принтером, он генерирует следующий вывод :

изображение:картинка/гиф:[Б изображение:картинка/гиф:Ява.Ио.InputStream в

изображение: изображение / gif: java.сеть.URL изображение: image / jpeg: [B

изображение: изображение / jpeg: java.Ио.InputStream изображение: image / jpeg: java.сеть.URL

изображение:изображение/png:[изображение B:изображение/png:Ява.Ио.InputStream в

изображение:изображение/png: java.сеть.URL

application:application/x-java-JVM-local-objectref: java.ОУ.печать.Pageable

application:application/x-java-JVM-local-objectref: java.ОУ.печать.Для печати

применение: применение / октет-поток: [B

application: application / octet-stream: java.сеть.URL

application: application / octet-stream: java.Ио.InputStream

вы можете заметить, что мой принтер не поддерживает "text/plain; charset=utf-16" вкус либо.

2), изменив ВКУС на DocFlavor.INPUT_STREAM.AUTOSENSE, у вас больше нет исключения, связанного с отсутствующей поддержкой DocFlavor.
Так это значит, что DocFlavor.INPUT_STREAM.AUTOSENSE поддерживается принтером.
Но ты встречаешься с другим. проблема, поскольку данные для печати не соответствуют объявленному типу, связанному с DocFlavor.INPUT_STREAM.AUTOSENSE :

IllegalArgumentException: данные не объявленного типа.

на DocFlavor, the INPUT_STREAM.AUTOSENSE константа объявляется следующим образом :

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

это соответствует последнему поддерживаемому аромату в предыдущем выходе:

application: application / octet-stream: java.Ио.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);