2015-07-16 4 views
10

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

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

  1. Первоначально, я думал, что DocFlavor не поддерживается. Затем я перечислил на поддерживаемый DocFlavor этого принтера, и один из них был application/octet-stream, который является DocFlavor.INPUT_STREAM.AUTOSENSE. Так что вкус поддерживается принтером.
  2. Затем я добавил PrintJobListener, чтобы проверить, не выполнено ли задание на печать . Когда я добавил слушателя к printJob, он печатает No_More_Events и DATA_TRANSFER_COMPLETE, который должен был напечатать JOB_COMPLETE, если работа выполнена успешно.
  3. Заключительный шаг - отладка кода 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. Ничего не работает, и я получаю ошибку времени выполнения, которая не поддерживается.

+0

Не могли бы вы обновить свой вопрос кодом, который вы пишете для печати файла? Как вы упомянули выше, код используется для записи в файл. – Parth

+0

Я думаю, что проблема в том, что вам нужно ** визуализировать ** pdf в первую очередь, вы не можете распечатать его напрямую, около 10 лет назад я сделал это с помощью функции автоматической печати acrobat cli ... ставка теперь есть альтернативы. – maraca

+0

@maraca: Я могу распечатать его на принтере Xerox, но не с Fuji. – Anand

ответ

0

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

Отрывок из Sample codes

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

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

+0

Я могу распечатать PDF без проблем на принтере Xerox. Но сталкиваются с проблемами с другим принтером, который сидит у клиента. – Anand

+0

@ Значит, вы хотите сказать, что ваша автоматическая печать работает с принтером Xerox, но не с типом Fuji. – Garry

+0

Да. этот тип принтера Fuji не печатается автоматически. – Anand

0

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

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

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

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

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

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

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

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

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

Смежные вопросы