РефератыИнформатика, программированиеДоДокументация на основе RTF-шаблона

Документация на основе RTF-шаблона

Александр Харьков, "Комиздат"


Разработка прикладного ПО - это, как известно, не только написание кода программ, но и проектирование печатных документов и отчетов. Практически все интегрированные среды имеют в своем составе генераторы отчетов, в той или иной степени помогающие решить эту задачу. Однако, несмотря на явные достоинства, использование генераторов отчетов имеет ряд недостатков. Они сводятся, главным образом, к невозможности вносить правки в сформированный документ, а также изменять шаблоны отчета привычными средствами, например обычным текстовым редактором.



До последнего времени самым простым и широко применяемым решением представлялось применение механизма OLE. Например, для комбинации Word и VisualBasic возможна такая схема:


Создаем некий файл - шаблон документа. Там, где должна быть "шапка" (дата, номер документа и др.), используем закладки, а для основной части отчета создаем таблицу-заготовку соответствующей структуры. Пример такого шаблона приведен на рис. 1.


Пишем программу с использованием объектной модели Word:


' NumStr - кол-во строк в отчете


' NewData (5,NumStr) - массив с данными для заполнения


' таблицы, заранее приведенными к символьному виду


' Itog - сумма, приведенная к символьному виду


' Pth - путь к исходному файлу


' Str_ndoc = "BS190"


' Str_name = "Петров И.И."


.................


Dim objWord As Word.Application


Dim objDoc As Word.Document


Dim objTable As Word.Table


' создаем объект Word


Set objWord = New Word.Application


' делаем его видимым - это не обязательно,


' но очень интересно :)


objWord.Visible = True


' открываем файл шаблона


Set objDoc = objWord.Documents.Open (Pth)


' делаем его активным


objDoc.Activate


' заполняем "шапку документа" - номер и получатель


' - закладки 'ndoc' и 'name' соответственно


objDoc.Bookmarks ("ndoc").Range.Text = Str_ndoc


objDoc.Bookmarks ("name").Range.Text = Str_name


' связывам объект с таблицей


Set objTable = objWord.ActiveDocument.Tables (1)


' выделяем 2-ю строку таблицы в шаблоне


objTable.Cell (2, 1).Range.Select


' вставляем нужное кол-во строк-1


' (т.к. одна уже есть в шаблоне)


If NumStr > 0 Then objWord.Selection.InsertRows (NumStr - 1)


' для каждой строки в каждую ячейку вставляем нужные


' данные из массива


For i = 1 To NumStr


For j = 1 To 5


objTable.Cell (i + 1, j).Range.Text = NewData (j, i)


Next j


Next i


' проставляем сумму "Всего"


objTable.Cell (NumStr + 2, 5).Range.Text = Itog


Запускаем ее в составе всего приложения и получаем результат (см. рис. 2).


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


Но эту идиллическую картину омрачает несколько неприятных моментов. Во-первых, недостаточная гибкость приложения - если вы захотите перейти на другой редактор, то придется писать код заново. Во-вторых, приложение работает только в среде пакета MS Office, а он стоит немалых денег. Если приложение должно работать на 30-ти компьютерах предприятия, то установка на них MS Office обойдется примерно в 40 тыс. гривен - не каждый бюджет выдержит.



В то же время существует целый ряд бесплатных и достаточно полнофункциональных офисных пакетов: OpenOffice, StarOffice, EasyOffice и др. Для большинства операций, выполняемых обычно с документами, их возможностей вполне достаточно. Но возможна ли их простая и эффективная интеграция в прикладное программное обеспечение?


Решением этой проблемы может быть использование RTF-файлов. Этот формат, предложенный Microsoft как стандарт для обмена данными между текстовыми редакторами, поддерживается абсолютным большинством офисных пакетов. Сама Microsoft использует его в качестве формата, в котором данные передаются через буфер обмена между различными приложениями Windows.


Кратко об RTF


В формате RTF используются только коды, представляемые символами из наборов ASCII, MAC и PC. Помимо текста, RTF-файл содержит команды управления в читаемой форме. Документ состоит преимущественно из команд управления настройкой программы чтения. Эти команды можно разделить на управляющие слова и управляющие символы.


Управляющее слово представляет собой последовательность символов с разделителем в конце. Например, фрагмент:


…bkmkstart ndoc…


соответствует началу закладки ndoc.


Перед управляющим словом вводится обратная косая черта (). В качестве разделителей могут использоваться следующие символы:


пробел, причем этот символ относится к управляющему слову;


цифра или дефис (<->). После этих символов должен следовать параметр с разделителем. В качестве разделителя может быть использован пробел или другие символы (кроме цифр и букв);


все символы, кроме цифр и букв. Эти символы не относятся к управляющему слову.


Для задания управляющей последовательности в RTF-формате используются буквы от А до Z и от а до z, а также цифры от 0 до 9. Национальные символы к управляющей информации не относятся.


В качестве управляющих символов используются отдельные буквы. Перед каждым управляющим символом вводится обратная косая черта (). Например, фрагмент:


…f1fs20…


устанавливает шрифт № 1 размером в 20 единиц.


Фрагмент RTF-файла приведен ниже. Структура его, как можно видеть, напоминает структуру HTML-документа:


intblphmrgposy371dxfrtext180dfrmtxtx180dfrmtxty0nowrap


aspalphaaspnumfaautoadjustrightrin0lin0f1fs20lang1049


langfe1049cgridlangnp1049langfenp1049{lang1033langfe1049


langnp1033 11cell 12cell 13cell} pard ql li0ri0widctlparintbl


aspalphaaspnumfaautoadjustrightrin0lin0


В RTF-формате существует возможность объединять отдельные последовательности в группы при помощи скобок:


{группа}


Такие группы создаются, например, при описании сносок, колонтитуло

в, закладок и т.п.


Вот некоторые управляющие слова и символы, имеющие непосредственное отношение к теме нашей статьи:


раr - конец абзаца;


сеll - конец столбца;


row - конец строки (или таблицы);


*bkmkstart <название закладки> *bkmkend - закладка. Пример: {*bkmkstart ndoc} BS190{*bkmkend ndoc};


pard - устанавливает стандартную настройку для абзаца;


intbl … intbl - выделяет область таблицы;


' - прямой ввод в текст шестнадцатеричных чисел. При сохранении кириллического текста он обычно сохраняется в шестнадцатеричной форме, например:


'd1'f2'f0'ee'ea'e0 ('строка')


Поскольку нас интересуют только определенные задачи, знания приведенных выше управляющих слов и символов вполне достаточно. Условимся для простоты называть управляющие слова и символы тегами.


А теперь рассмотрим алгоритмы решения трех основных задач, возникающих при создании документации.


Вставка строки на месте закладки


Пример такой закладки:


…{*bkmkstart ndoc}<значение закладки>{*bkmkend ndoc}…


Для решения данной задачи можно предложить следующий алгоритм.


Читаем последовательно строки входного файла (в большинстве случаев строка больше 255 символов).


Ищем в текущей строке тег 'bkmkstart'.


Если находим, то выделяем название закладки и сравниваем его с искомой.


Если совпадает, то записываем строковую строку данных после закрывающей скобки (}).


Алгоритм реализован в виде функции In_Zakl1(pth As String, zakl As String, data As String), где pth - имя RTF-файла, zakl - имя закладки, data - строка для добавления в файл.


Добавление строк в таблицу


Предположим, нам требуется найти m-ю строку в n-той таблице и повторить ее в этой таблице p раз. Для поиска начала строки таблицы мы будем использовать тег intbl, а для поиска конца - тег row. Конец самой таблицы определяется по последовательности тегов row…pard…par.


Алгоритм решения этой задачи следующий.


Читаем последовательно строки входного файла.


Ищем последовательность …row…pard…par…intbl… (не обязательно в одной строке) (n-1) раз. После этого мы находимся в начале нужной таблицы.


Ищем тег row (m-1) раз. После этого находимся перед нужной строкой таблицы.


Ищем следующий тег row и копируем содержимое файла от (m-1)-го до m-го тега row (между row и intbl содержатся настройки строки, они нам тоже нужны).


Вставляем после m-го тега row скопированную нами подстроку p раз.


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


Алгоритм реализован в виде функции In_TStr (pth As String, itbl As Integer, irow As Integer, kol As Integer), где pth - имя RTF-файла, itbl - номер таблицы, irow - номер строки, kol - количество повторов строки.


Заполнение ячейки таблицы


Представим, что требуется найти k-ю ячейку в m-й строке n-й таблицы и вставить в нее текстовую строку данных. Пример таких ячеек:


...{lang1033cgrid0<содержимое 1-й ячейки>


cell<содержимое 2-й ячейки>cell}…


Задача может быть решена по следующему алгоритму.


Читаем последовательно строки входного файла.


Ищем последовательность …row…pard…par…intbl… (не обязательно в одной строке) (n-1) раз. После этого мы находимся перед нужной нам таблицей.


Ищем тег row (m-1) раз. После этого мы находимся в начале нужной строки таблицы.


Ищем k-e вхождение тега cell.


Вставляем перед ним строку данных.


Данный алгоритм реализован в виде функции In_Tcell1(pth As String, itbl As Integer, irow As Integer, icell As Integer, ndata As String), где pth - имя RTF-файла, itbl - номер таблицы, irow - номер строки, icell - номер ячейки, data - строка для занесения в ячейку.


Программа на VisualBasic, демонстрирующая применение такой технологии и функционально идентичная программе, приведенной в начале этой статьи, выглядит так:


' NumStr - кол-во строк в отчете


' NewData (5,NumStr) - массив с данными для заполнения


' таблицы, заранее приведенными к символьному виду


' Itog - сумма, приведенная к символьному виду


' pth - путь к файлу


' Str_ndoc = "BS190"


' Str_name = "Петров И.И."


Dim res As Boolean ' результат выполнения функций


' заполняем "шапку документа" - номер и получатель


' - закладки 'ndoc' и 'name' соответственно


res = In_Zakl1(pth, "ndoc", Str_ndoc)


res = In_Zakl1(pth, "name", Str_name)


' вставляем нужное кол-во строк-1


' (т.к. одна уже есть в шаблоне)


res = In_TStr (pth, 1, 2, NumStr - 1)


' для каждой строки в каждую ячейку вставляем


' нужные данные из массива


For i = 1 To NumStr


For j = 1 To 5


res = In_Tcell1(pth, 1, i + 1, j, NewData (j, i))


Next j


Next i


res = In_Tcell1(pth, 1, NumStr + 2, 5, Itog)


' проставляем сумму "Всего"


Заключение


Каковы преимущества и недостатки предложенной технологии? Начнем с достоинств. Во-первых, это более гибкая технология для формирования отчетов - даже если часть пользователей работает с OpenOffice, а часть с MS Office, программа создания отчетных документов универсальна. Во-вторых, несмотря на многоразовую перезапись файла шаблона во время работы, эта программа работает быстрее, чем связка OLE+Word. Тем более что приведенные выше алгоритмы могут совершенствоваться. Один из примеров кардинального повышения производительности приведен в листингах варианта для PascalDelphi. В-третьих, пользуясь свободным ПО, вы экономите деньги.


Теперь о проблемах. Основная из них - это недостаточная стандартизация формата RTF. Производители ПО, в целом придерживаясь единого стандарта, допускают несколько свободную трактовку частных моментов. Результат - проблемы с использованием "чужих" RTF-файлов, подготовленных в других редакторах. Например, MS Word сохраняет графические изображения внутри RTF-файла в виде последовательности шестнадцатеричных кодов, а OOWriter - как внешний файл.


Впрочем, эти проблемы решаются - стоит только приложить некоторые усилия.

Сохранить в соц. сетях:
Обсуждение:
comments powered by Disqus

Название реферата: Документация на основе RTF-шаблона

Слов:1713
Символов:13852
Размер:27.05 Кб.