Автоматическая печать не работает в Java

У меня есть требование распечатать PDF файлы двумя разными способами - через веб-страницу, где пользователь увидит предварительный просмотр печати и выберет принтер и распечатает его. Второй способ - автоматизировать печать, просто нажав кнопку, PDF следует отправить на принтер.

Первый способ печати через веб-страницу работает нормально, но не второй. Принтер по умолчанию успешно извлекается для автоматической печати, но не печатается, и я также не получаю никаких ошибок. Ниже приведен мой анализ:

  • Сначала я думал, что DocFlavor не поддерживается. Затем я перечислил вниз поддерживаемый DocFlavor этого принтера, и один из них был application/octet-stream, который равен DocFlavor.INPUT_STREAM.AUTOSENSE. Таким образом, вкус поддерживается принтером.
  • Затем я добавил PrintJobListener, чтобы проверить, выполнено ли задание на печать не смогли. Когда я добавил слушателя к printJob, он печатает No_More_Events и DATA_TRANSFER_COMPLETE, которые должны быть напечатаны JOB_COMPLETE, если задание выполнено успешно.
  • Последний шаг - отладка кода Java. Когда я выполнил линию job.print(), он переходит в метод Win32PrintJob.print(). Я сделал F6 до выполните каждую строку, чтобы увидеть, что она делает. Я сравнил его с кодом в GrepCode, поскольку исходный код не был загружен в eclipse. Это все идет хорошо, и я не вижу никакой ошибки. Единственное, что он сделал не входит в этот блок, где он проверяет mDestination потому что я не предоставил его, он не прошел.

См. код ниже:

if (mDestination != null) { // if destination attribute is set
    try {
        FileOutputStream fos = new FileOutputStream(mDestination);
        byte [] buffer = new byte[1024];
        int cread;

        while ((cread = instream.read(buffer, 0, buffer.length)) >= 0) {
            fos.write(buffer, 0, cread);
        }
        fos.flush();
        fos.close();
    } catch (FileNotFoundException fnfe) {
        notifyEvent(PrintJobEvent.JOB_FAILED);
        throw new PrintException(fnfe.toString());
    } catch (IOException ioe) {
        notifyEvent(PrintJobEvent.JOB_FAILED);
        throw new PrintException(ioe.toString());
    }
    notifyEvent(PrintJobEvent.DATA_TRANSFER_COMPLETE);
    notifyEvent(PrintJobEvent.JOB_COMPLETE);
    service.wakeNotifier();
    return;
}

Это единственное место, где указано JOB_COMPLETE. Я думаю, что этот блок должен записывать в файл, который мне не нужен.

Я думаю, что фактическая печать выполняется в следующей строке тем же методом Win32PrintJob.print().

private native boolean More ...printRawData(byte[] data, int count);

Но этот метод является родным, поэтому я не знаю, что происходит внутри этого.

Пожалуйста, дайте мне знать, почему я не могу распечатать PDF.

EDIT:

Прикрепленный код для печати файла:

PrintService pss = PrintServiceLookup.lookupDefaultPrintService();
DocPrintJob job = pss.createPrintJob();
DocAttributeSet das = new HashDocAttributeSet();
Doc document;
try {
    document = new SimpleDoc(new FileInputStream(new File(fileName)), DocFlavor.INPUT_STREAM.AUTOSENSE, das);

    PrintRequestAttributeSet pras = new HashPrintRequestAttributeSet();
    job.addPrintJobListener(new PrintJobWatcher());
    job.print(document, pras);
}

ПРИМЕЧАНИЕ. Я пробовал разные варианты, такие как PDF, PCL. Ничего не работает, и я получаю ошибку времени выполнения, которая не поддерживается.

Ответ 1

Вы пробовали JPadel для печати PDF файлов:

Выдержка из Примеры кодов

final PdfBook pdfBook = new PdfBook(pdfDecoder, printJob.getPrintService(), attributes);
pdfBook.setChooseSourceByPdfPageSize(false);

final SimpleDoc doc = new SimpleDoc(pdfBook, DocFlavor.SERVICE_FORMATTED.PAGEABLE, null);

// used to track print activity
printJob.addPrintJobListener(new PDFPrintJobListener());

try {
    printJob.print(doc, attributes);
}
catch (final Exception e) {
    LogWriter.writeLog("Exception " + e + " printing");
    // <end-demo>
}

В дополнение к этому вы можете указать имя принтера и добавить listner PDFPrintJobListener.

Ответ 2

Недавно у меня была одна и та же задача, и ответ был не таким прямым для второго варианта печати (также использовался JPedal, Samba и другие решения..). Самый простой способ печати (который я в конечном итоге пробовал) состоял в том, чтобы просто поместить файл в очередь принтера, a.k.a в корневую папку. Пример: MY_SERVER\PRINTER_NAME\

Теперь проблема становится средой /O.S, а не Java. Через приложение, установленное на компьютере с Windows, вы можете получить доступ к этой папке, скопировать файл, который вы хотите распечатать, и вуаля. Кроме того, используя методы, которые вы используете, вы также можете указать задание на печать имя, количество копий и т.д.

Однако, как только приложение установлено на сервере, это совершенно другая игра с мячом, особенно если вы работаете с серверами Linux.

Прежде всего, вам нужно будет перевести адреса Windows на Linux, чтобы даже попытаться скопировать файл/распечатать его.

Во-вторых, и это очень важно, для принтера очень редко/сложно или просто "принять файл" для печати, если он не является частью более сложного/запатентованного потока данных. Например, вы можете узнать, что принтеры "язык общения" с сервером или даже с вашим компьютером, когда вы делаете "Ctrl + P".. это будут в основном файлы .xml или какой-либо другой формат.

Но/и для того, чтобы "вычеркнуть" этот формат, вам придется разработать (в конечном счете, на Java) апплет, который будет называть этот принтер.

Конечно, вы также можете попробовать установить Cups4j на этом сервере или настроить сервер печати (при условии, что там, где вы работаете, это не на месте), но это вызовет проблемы при изменении принтеров, добавлении в сеть, и т.д.

В конечном итоге либо вы придерживаетесь подхода "Ctrl + P", создайте немного JS script, который вызывает "CTRL + P" в браузере или начнет воссоздать колесо, что не так уж плохо (поскольку есть люди, которые тоже выбирают этот подход... но я нигде не нашел примера), но у вас будет больше времени, чем у вас.

Надеюсь, я помог в некотором роде (извините за длинный пост... но это тема, которую я искал и работал в течение хорошего периода времени).