на главную обучение сертификация статьи литература ссылки гостевая книга
  Список статей Оглавление Текст статьи  

Печать документов на принтере в Java

Автор:Качалов Михаил Викторович
Создан:07.05.2002


6. Современные методы печати

6.1 Введение

   Библиотека классов java.awt.print описаная выше достаточно удобна для печати как одностраничных, так и многостраничных документов, однако у нее имеется неочевидный при первом рассмотрении недостаток: внешний вид страниц необходимо формировать с помощью самостоятельно созданных классов и методов. Такой подход вполне допустим если приложение разрабатываемое программистом должно формировать бланки или отчеты заранее определенного вида, но такой подход становится неудобным в случае создания универсальной программы печати документов различных форматов, например текстовых файлов, HTML-страниц, PDF-документов и т. п.
   Еще один на первый взгляд не заметный недостаток печати при помощи Java 1.2 API - оконные диалоги, возникающие при печати не являются истинно платформенно независимыми. В различных операционных системах диалоговые окна настроек принтера и настроек страницы будут иметь различный внешний вид.
   К недостаткам вышеописанных классов можно также отнести отсутствие возможности обрабатывать события связанные с принтером, что могло бы быть полезным при печати длинных документов, когда важно проследить не прервалась ли работа принтера и не изменились ли его настройки, и не очень высокую производительность печати, так как принтер печатает подготовленное изображение, т. е. работает в графическом режиме, в то время, как у многих принтеров существуют текстовые режимы печати, существенно более производительные, чем графический режим.
   Описаные выше проблемы на сегодняшний день решаются с помощью дополнительных классов и методов для печати появившихся в Java 1.4 API. Все дополнительные к Java 1.2 API классы для печати сгруппированы в пакете javax.print и его подпакетах.

   Принципиальное отличие нового API заключается в том, что при печати учитывается медиа тип содержимого документа, задаваемый при помощи стандартных, определенных в RFC-документах 2045 и 2046, MIME-типов (Multipurpose Internet Mail Extensions Types). Существует достаточно много MIME-типов форматирования данных, "понимаемых" Java 1.4 API, например: "text/plain" - текстовые ASCII документы, "text/html" - документы формата HTML, "application/pdf" - документы формата PDF, "application/postscript" - документы формата PostScript, "image/gif" и "image/jpeg" - соответствующие графические форматы, и т. д. Помимо возможности печатать предварительно отформатированные документы, сохранилась также возможность печати документов формируемых в пользовательских Java-классах, реализующих интерфейс java.awt.print.Printable. Таким источникам данных для печати соответствует MIME-тип "application/x-java-jvm-local-objectref". Для обозначения данных такого типа в англоязычной литературе используют термин "service formatted print data", а для данных стандартных MIME-типов, извлекаемых из некоторого источника, где они уже находились в предварительно отформатированном виде используют термин "client formatted print data".

   Практически для осуществления печати документа, с помощью Java 1.4 API, необходимо выполнить следующую последовательность действий:
  1. Получить список доступных системе принтеров
  2. Создать объект для дальнейшего взаимодействия с принтером
  3. Описать тип форматирования (MIME-тип) печатаемых данных
  4. Задать свойства печати (количество и формат листов и т. п.)
  5. Установить связь с источником данных
  6. Распечатать данные
6.2 Получение списка принтеров

   В качестве объекта идентифицирующего системный принтер выступает объект реализующий интерфейс javax.print.PrintService. Получение ссылки на этот объект производится с помощью специальных "поисковых" методов класса PrintServiceLookup:
  • public static PrintService lookupDefaultPrintService() - отыскивает принтер по умолчанию, в случае если такой принтер отсутствует, возвращает null

  • public static PrintService[] lookupPrintServices(DocFlavor flavor,AttributeSet attributes) - отыскивает все доступные операционной системе принтеры, удовлетворяющие заданым требованиям (например способных печатать документы формата A3). Если в качестве аргументов указать значения null, то вернется массив из всех принтеров доступных ОС пользователя
   Пример кода, выполняющего описанное действие:
	PrintService printService=
		PrintServiceLookup.lookupDefaultPrintService();

6.3 Создание объекта для взаимодействия с принтером

   Для взаимодействия с принтером используется объект типа javax.print.DocPrintJob по применению схожий с объектом типа java.awt.print.PrinterJob, применявшемся в Java 1.2 API. Ссылку на этот объект получают с помощью метода public DocPrintJob createPrintJob() объекта реализующего интерфейс PrintService.
   Пример кода, выполняющего описанное действие:
	DocPrintJob job=printService.createPrintJob();

6.4 Описание типа форматирования печатаемых данных

   Описание типа форматирования тех данных, которые позже будут отпечатаны принтером, осуществляется с помощью объекта типа javax.print.DocFlavor и его вложеных классов. Принципиально класс DocFlavor содержит информацию о MIME-типе печатаемых данных, кодировке, если это данные текстовые, и типе источника данных в виде полностью определенного имени Java-класса (например: java.io.FileInputStream).
   Источник данных может поставлять данные в разном виде, причем выделяют два основных вида представления данных:
  1. Client Formatted Print Data - предварительно сформированные данные
  2. Service Formatted Print Data - динамически формирующиеся данные
   Под предварительно сформированными данными подразумеваются данные читаемые в виде потока из файла или по сети. При потоковом чтении данных различают байтовые и символьные потоки. Обработка байтовых потоков производится с помощью вложенных классов класса DocFlavor:
  • javax.print.DocFlavor.BYTE_ARRAY - позволяет обрабатывать данные поступающие из байтового массива - источник byte[]
  • javax.print.DocFlavor.INPUT_STREAM - позволяет обрабатывать данные поступающие из байтового потока ввода - источник java.io.InputStream
  • javax.print.DocFlavor.URL - позволяет обрабатывать данные поступающие из сетевого источника байтовых данных - источник java.net.URL
   Для обработки текстовых потоков используются аналогичные вложенные классы:
  • javax.print.DocFlavor.CHAR_ARRAY - позволяет обрабатывать данные поступающие из символьного массива - источник char[]
  • javax.print.DocFlavor.READER - позволяет обрабатывать данные поступающие из текстового потока чтения - источник java.io.Reader
  • javax.print.DocFlavor.STRING - позволяет обрабатывать данные поступающие из текстовой строки - источник java.lang.String
   Каждый из этих классов может обрабатывать данные популярных MIME-типов на работу с которыми он расчитан. При этом "Java" понимает не все типы форматирования данных, но многие популярные типы могут быть прочитаны этими классами и отпечатаны с учетом особенностей форматирования применявшихся в иточниках данных. В каждом из этих классов описаны статические константы определяющие какие MIME-типы данных может обрабатывать этот класс:

Класс BYTE_ARRAY
константакомментарий
AUTOSENSE соответствует MIME-типу "application/octet-stream", печатает данные "как есть", без разбора формата, что хорошо подходит для текстовых документов формата *.txt
GIF соответствует MIME-типу "image/gif"
JPEG соответствует "image/jpeg"
PNG соответствует "image/png"
PDF соответствует "application/pdf"
POSTSCRIPT соответствует "application/postscript"
TEXT_HTML_US_ASCII соответствует "text/html;charset=us-ascii"
TEXT_PLAIN_US_ASCII соответствует "text/plain;charset=us-ascii"
Класс INPUT_STREAM
константы этого класса, такие же, как и в классе BYTE_ARRAY
Класс URL
константы этого класса, такие же, как и в классе BYTE_ARRAY
Класс CHAR_ARRAY
TEXT_HTML соответствует "text/html;charset=utf-16"
TEXT_PLAIN соответствует "text/plain;charset=utf-16"
Класс READER
константы этого класса, такие же, как и в классе CHAR_ARRAY
Класс STRING
константы этого класса, такие же, как и в классе CHAR_ARRAY

   В качестве динамически формирующихся данных выступают данные для печати формирующиеся методами применявшимися для печати в Java 1.2 API. Для их описания применяется еще один вложенный класс класса DocFlavor:
  • javax.print.DocFlavor.SERVICE_FORMATTED
   В этом классе также определены статические константы, описывающие разные способы формирования документа для печати:
  • PAGEABLE - соответствует данным представленным в виде объекта, реализующего интерфейс java.awt.print.Printable
  • PRINTABLE - соответствует данным представленным в виде объекта, реализующего интерфейс java.awt.print.Pageable (например класс Book)
  • RENDERABLE_IMAGE - соответствует данным представленным в виде объекта, реализующего интерфейс java.awt.image.renderable.RenderableImage
   Пример кода указания формата и источника данных:
	DocFlavor docFlavor=DocFlavor.INPUT_STREAM.AUTOSENSE;
   Прежде чем указывать формат и источник данных, желательно убедиться, что такие форматы и источники поддерживаются установленными у вас Java-библиотеками, так как не все медиа-типы из описаных выше имеют реальную поддержку. Для этого можно воспользоваться например таким кодом, проверющим возможность работы с изрображениями формата JPEG, считываемыми из потока ввода:
	PrintService printService=
		PrintServiceLookup.lookupDefaultPrintService();
	DocFlavor[] docFlavors=
		printService.getSupportedDocFlavors();
	DocFlavor testFlavor=
		new DocFlavor("image/jpeg","java.io.InputStream");
	for(int i=0;i<docFlavors.length;i++){
		if(docFlavors[i].equals(testFlavor)){
			...
			break;
		}
	}
   А чтобы увидеть список всех поддерживаемых в вашей системе форматов, можно использовать следующий код:
	
	DocFlavor[] docFlavors=
		printService.getSupportedDocFlavors();
	for(int i=0;i<docFlavors.length;i++){
		System.out.println(docFlavors[i].toString());
	}

6.5 Задание свойств печати

   Все вышеописанные классы позволяют выбрать тип источника данных и формат, в котором эти данные поставляются. Кроме того, при печати документа желательно указать ориентацию листа (книжную или альбомную), размеры полей на листе и количество копий при печати. Эти и другие подобные им настройки печати хранятся в объектах типа:
  • DocAttributeSet - объединяет свойства страницы (поля, размеры)
  • PrintRequestAttributeSet - объединяет свойства печати (количество копий, качество печати)
    и других
   Эти интерфейсные классы хранятся в пакете javax.print.attribute и описывают коллекции свойств принтера и листа. Сами свойства описываются классами из пакета javax.print.attribute.standard. В частности:
  • MediaSize - задает размеры листа
  • MediaPrintableArea - задает размеры области печати на листе
  • OrientationRequested - указывает орниентацию листа
  • Copies - задает количество копий при печати
  • PrintQuality - указывает качество печати: низкое/нормальное/высокое
  • JobName - указывает имя задания в списке заданий на печать
    и другие
Попробуем создать объекты с описанием свойств страницы и печати:
	DocAttributeSet docAttributes=
		new HashDocAttributeSet();
	docAttributes.add(OrientationRequested.PORTRAIT);
	PrintRequestAttributeSet printAttributes=
		new HashPrintRequestAttributeSet();
	printAttributes.add(new Copies(2));

6.6 Связывание медиа-типа документа и свойств документа с источником данных

   Связывание источника данных для печати с настройками страницы, которые необходимо использовать при печати, обычно осуществляется с помощью класса javax.print.SimpleDoc, реализующего интерфейс javax.print.Doc.

Свяывание источника данных  и свойств страницы

   Объект реализующий интерфейс Doc это и есть тот объект, который в дальнейшем распечатается с помощью класса PrinterJob. Ниже приводится пример создания объекта для печати, причем подразумевается, что данные извлекаются из потока, связанного с файлом:
	Doc doc=new SimpleDoc(new FileInputStream("test.txt"),
				docFlavor,
				docAttributes);
   Источники данных могут быть различными, в зависимости от поддерживаемых системой медиа-типов. В нашем случае (см. выше) был использован поток чтения данных типа java.io.InputStream без обработки внутреннего форматирования, что указано в объекте типа DocFlavor помощью MIME-типа "application/octet-stream". По прежнему можно в качестве источника данных использовать объект типа Printable или Pageable, представляющий собой изображение для печати, формируемое программно, путем переопределения метода print().

6.7 Печать документа

   Постановка задания на печать осуществляется вызовым метода public void print(Doc doc,PrintRequestAttributeSet attributes)throws PrintException принадлежащего объекту реализующему интерфейс javax.print.DocPrintJob. Пример, кода реализующего такое действие, приведен ниже:
	try{
		job.print(doc,printAttributes);
	}catch(PrintException e){
		...
	}


назад оглавление дальше