Печать из браузера средствами CSS

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

Например, еще несколько лет назад было бы вполне нормально сделать систему регистрации и учета клиентов скажем стоматологической поликлиники или библиотеки в Delphi, добавить базу данных и сетевую часть. Но сейчас такое решение окажется неразумным: гораздо проще, удобнее, а значит и эффективнее использовать все то, что предоставляет нам Web, даже если приложением будут пользоваться только внутри локальной сети. Кроме того, такое решение кроссплатформенное, что актуально в связи с наметившейся тенденцией перехода к свободным ОС. Все что нужно на клиентских компьютерах - наличие браузера, никаких установок, настроек и прочего.

Но у решения все делать в web есть недостаток (даже не один, но я сейчас не буду перечислять все): неудобство при печати отчетов, бланков документов и прочих печатных страниц. Это связано с тем, что веб-страницы рассчитываются прежде всего для отображения на экране монитора и не подтачиваются для печати, что нередко ведет к расползанию печатной страницы. К счастью это все временные трудности и их можно обойти. Можно, например, генерировать отчеты в pdf или doc. Но я считаю это не слишком удобным: пользователю надо устанавливать программы, работающие с этими форматами, каждый раз выкачивать с сервера сгенерированный файл, печатать из сторонней программы, а не браузера. Поэтому стоит приложить усилия к созданию страниц, правильно выводящихся на печать прямо из браузера.


Раз имеются отдельные версии страницы для отображения на экране и для печати, то следует разделить CSS на две части по назначению. Свойства элементов, специальные для отображения на экране будут храниться в блоке
@media screen {}
а для печати, соответственно, в
@media print {}

Первое, что нужно сделать - отключить все лишние графические элементы: баннеры (в веб-приложении для локальной сети врядли они будут), меню, еще что-нибудь. Достигается это следующей конструкцией в CSS:

@media print {
.banner {display:none;}
}

Также запрещаем отображение других лишних блоков. Возможно, некоторые блоки наоборот стоит отображать при печати, а на экране скрывать. Красивый цветной логотип наверняка на черно-белом принтере распечатается грязным или недостаточно четким, стоит подменить его на специальный контрастный:
@media screen {
div.logo {background: url(img/logo.png) no-repeat top;}
}
@media print {
div.logo {background: url(img/logo_print.png) no-repeat top;}
}

Скорее всего пользователь веб-приложения будет распечатывать страницу на принтере формата A4 (если только это приложение не для полиграфии). Ограничим страницу нужным размером, вставив конструкцию @page. Можно указать размеры страницы (обязательно в сантиметрах или дюймах, ни в коем случае не в пикселах!), так для A4 это 8.5x11 дюймов или 21x29.7 см.
@page {
size 8.5in 11in;
margin: 1cm
}

Если предполагается двухсторонняя печать, то следует различать левую и правую страницы:
@page :left {
margin-left: 4cm;
margin-right: 3cm;
}

@page :right {
margin-left: 3cm;
margin-right: 4cm;
}

Также размеры всех элементов на странице стоит задавать в относительных единицах. Не помешает подменять шрифт: на бумаге лучше смотрятся шрифты с засечками.

При печати многостраничных отчетов или заполненных бланков документов потребуется каждую часть отчета или каждый бланк выводить на отдельную страницу. Мне показалось очень удобным на экране показать разрыв страницы с помощью горизонтальной черты hr, а при печати по ней делать разрыв страницы:
@media print {
hr {PAGE-BREAK-AFTER: always; visibility: hidden;}
}

Напомню, что PAGE-BREAK-AFTER заставляет принтер продолжить печать со следующей страницы после вывода элемента с этим свойством, а PAGE-BREAK-BEFORE - перед выводом. В приведенном мной примере hr при печати не отображается (visibility: hidden), но это не мешает ему управлять принтером.

В одном из моих проектов оператору нужно было заполнять форму с данными клиента, после чего ему может понадобиться распечатка этой формы со специальным форматированием. Я решил на одной странице объединить и версию для отображения на экране с полями ввода формы и версию для печати. Это упрощает задачу оператора: достаточно после ввода данных и сохранения нажать кнопку "Распечатать" без загрузки специальной страницы.

Для этого я сформировал форму ввода данных в виде пустого бланка документа. Кстати, это хорошая идея: форма получается компактная и выглядит почти как на бумаге. Далее собираем на одной странице две версии документа, ловко манипулируя свойством display. Каждое поле в HTML выглядит так (упрощенно):

<td>ФИО клиента:</td>
<td><input type=text name=client_name size=30 value="Вася Пупкин"/>
<span class=field>Вася Пупкин</span></td>


Обратите внимание на этот span - в нем дублируется значение поля. CSS-файл такой:

@media screen {
.field {display: none;}
}
@media print {
input {display: none;}
td {border: 1px solid;}
.field {text-decoration: underline;}
}

Таким образом при отображении на экране мы видим поля ввода, а при печати - готовый результат.

Напоследок хочу сказать об одном неприятном моменте. Браузером устанавливаются свои поля страницы и колонтитулы. Это может разом испортить весь красиво сформированный бланк документа или растянуть страницу на две. JavaScript эту проблему не решит. Поэтому остается лишь попросить пользователя (высветив напоминание) убрать в браузере поля и колонтитулы.

Автор: http://maovrn.habrahabr.ru/



Опубликовал admin
12 Янв, Суббота 2008г.



Программирование для чайников.