Пример rtf-бланка
Заголовок документа: PARAM1
Строка 1 | Значение | PARAM2 |
Строка 2 | Значение | PARAM3 |
Подпись под документом: PARAM4
Рис.1 Пример бланка в виде rtf-файла, переменные описаны в виде полей типа “QUOTE” – PARAM1,PARAM2,PARAM3,PARAM4
При заполнении бланка данными, переменные PARAM1…4 должны будут замениться на свои значения.
При этом форма бланка обычно остается постоянной и неизменной, а конкретные поля в бланке необходимо “подгружать” из таблиц баз данных, файлов с данными и т.д. В терминах языка Perl – значениями хеша, ключи которого соответствуют названиям переменных:
(PARAM1=>”ПАРАМЕТР1”, PARAM1=>”ПАРАМЕТР2”, PARAM1=>”ПАРАМЕТР3”,
PARAM1=>”ПАРАМЕТР4”)
В результате, готовый к печати на лазерном принтере бланк, будет иметь примерно такой вид:
Пример rtf-бланка
Заголовок документа: ПАРАМЕТР1
Строка 1 | Значение | ПАРАМЕТР2 |
Строка 2 | Значение | ПАРАМЕТР3 |
Подпись под документом: ПАРАМЕТР4
Рис.2 Результат заполнения rtf-бланка (рис.1) заменой полей типа “QUOTE” на значения соответствующих ключей хеша.
При этом возникает необходимость выполнить несколько трудносовместимых требований -разработка и исправление бланка должно быть доступно конечному пользователю (бухгалтеру, сотруднику отдела кадров, менеджеру и т.д.) и позволять произвольно расставлять поля для слияния данных, а подготовка процедуры извлечения данных — программисту или сотруднику службы поддержки, то есть, необходимо отделить представление данных от процедуры извлечения данных.
Можно, разумеется, сказать, что подобная технология слияния данных давно используется в MS Word, например, но она имеет серьезный недостаток: процедура слияния довольно сложна для неподготовленного пользователя (необходимо подготовить файл с данными, выбрать бланк, запустить процесс слияния, разобраться с результатами).
Другой вариант – использование бланков в форме XML-файлов и заполнение их в соответствии с правилами подстановки, описанными в XSLT-таблицах,- имеет тот недостаток, что неподготовленному пользователю, привыкшему работать с MS Word будет трудно создавать и редактировать бланки XML-файлов. Какой-либо общераспространенный инструмент для работы с XML, сравнимый по популярности с MS Word трудно найти.
Выходом, разработанным и апробированным уже в течение ряда лет при работе в крупной банковской информационной системе стал вариант автоматической подстановки данных в rtf-бланки отчетов с использованием простого скрипта (в данном случае использовался perl, но возможно использование любого языка, поддерживающего обработку регулярных выражений), осуществляющего поиск в текстовом rtf-документе описателей полей типа “QUOTE” и замену символических названий этих полей на значение переменной с аналогичным именем, извлеченной из таблицы БД, файла данных (в терминах perl – из хеша по ключу, соответствующему символическому названию поля).
Пример скрипта c комментариями, выполняющего подобную подстановку, приведен в конце постинга.
Скорее всего, даже краткого пояснения принципа работы скрипта не требуется (готовый rtf-бланк с выполненными подстановками значений переменных выводится во временный файл temp.rtf, подготовленный к отправке на принтер), единственная представляющая в нем интерес часть – регулярное выражение:
$rtf =~ s/\{\\field\b[^{}]*\{\\\*\\fldinst.*?{\\fldrslt\s*\{([^}]+\s)?\s*([^}]+\s) ?\s*([^}]+)\}\s*((?:\{[^{}]+\}\s*)*)\}\s*\}/dosubst($1,$2,$3,$p,$&)/gesx;
осуществляющее поиск в rtf-файле описателей полей типа “QUOTE” и замену их соответствующим значением из хеша %p, возвращаемым функцией dosubst. Работоспособность этого регулярного выражения проверена на rtf-файлах, подготавливаемых всеми пакетами MS Office – от Office 95 до Office 2010.
Конечно, данный способ имеет некоторые недостатки, например, довольно трудно осуществлять вывод в rtf-бланк табличных значений, особенно для длинных таблиц, (их, например, можно выводить сразу в готовом виде, строя в perl-скрипте), но имеет и серьезные плюсы:
— разработку бланка и расстановку в нем полей для размещения данных может выполнять обычный пользователь, знакомый с редактором Word (умеющий вставлять в текст поля типа “QUOTE”), сообщающий затем список названий полей данных и что в них желательно помещать при подстановке программисту или специалисту службы поддержки;
— разработку скрипта, выгружающего данные, осуществляет программист, а в дальнейшем, при необходимости косметических изменений бланка (шрифт, отступы, логотип и т.д.), программиста привлекать необходимости нет, с этой работой легко справляется или служба поддержки, или сам пользователь – автор бланка.
Таким образом, легко выполняется разделение формы представления данных, за которую отвечает пользователь или служба поддержки, от собственно данных, процедуру извлечения которых разрабатывает программист.
#!/usr/bin/perl # filling rtf-blank # Dim Kobzev, Andrew Sapognikov # 2004 $==1000; #-------------------------filling template file------------------------------- sub dosubst { my ($pfx, $key, $xtrakey, $parm, $str) = @_; if (defined $xtrakey) { $xtrakey =~ s/[{}]//g; $xtrakey =~ s/\\w+//g; $xtrakey =~ s/\s//g; $key .= $xtrakey; } defined ($parm->{$key}) or return "\{$pfx\}"; my $val = $parm->{$key}; $val =~ s/([{}\\])/\\$1/g; $val =~ s/\n/\\line/g; $val =~ s/\r//g; return "\{$pfx$val\}"; } sub template ($$) { #filling $filename with hash $p my ($filename,$p)=@_; my $rtf; local $/, *F; open (F,"< $filename") or die "Cannot open $filename"; $rtf=<F>; close(F); #set win-1251 codepage $rtf =~ s/\\f(5|6)\\fmodern\\fcharset0/\\f$1\\fmodern\\fcharset144/; $rtf =~ s/\{\\field\b[^{}]*\{\\\*\\fldinst.*?{\\fldrslt\s*\{([^}]+\s) ?\s*([^}]+)\}\s*((?:\{[^{}]+\}\s*)*)\}\s*\}/dosubst($1,$2,$3,$p,$&)/gesx; return $rtf; }; #-------------------------main-------------------------------------------------- %p=('PARAM1'=>"ПАРАМЕТР1",'PARAM2'=>"ПАРАМЕТР2", 'PARAM3'=>"ПАРАМЕТР3",'PARAM4'=>"ПАРАМЕТР4"); my $tfil='temp.rtf'; open *FILE, "> $tfil" or die "Cannot open temporary file $tfil"; print FILE template("blank.rtf",\%p); close *FILE; #---------------------------------end main-------------------------------------
ссылка на оригинал статьи http://habrahabr.ru/post/156805/
Добавить комментарий