Мельница данных - Создание шаблонов PDF-отчетов  (раздел целиком)  (26.05.2019)
Создание шаблонов PDF-отчетов

1. Описание

Portable Document Format (PDF) — кроссплатформенный формат электронных документов, созданный фирмой Adobe Systems с использованием ряда возможностей языка PostScript. В первую очередь предназначен для представления в электронном виде полиграфической продукции, — значительное количество современного профессионального печатного оборудования может обрабатывать PDF непосредственно. Для просмотра можно использовать официальную бесплатную программу Adobe Reader, а также программы сторонних разработчиков. Традиционным способом создания PDF-документов является виртуальный принтер, то есть документ как таковой готовится в своей специализированной программе — графической программе или текстовом редакторе, САПР и т. д., а затем экспортируется в формат PDF для распространения в электронном виде, передачи в типографию и т. п. Формат PDF позволяет внедрять необходимые шрифты (построчный текст), векторные и растровые изображения, формы и мультимедиа-вставки. Поддерживает RGB, CMYK, Grayscale, Lab, Duotone, Bitmap, несколько типов сжатия растровой информации. Имеет собственные технические форматы для полиграфии: PDF/X-1, PDF/X-3. Включает механизм электронных подписей для защиты и проверки подлинности документов. В этом формате распространяется большое количество сопутствующей документации. Чаще всего PDF-файл является комбинацией текста с растровой и векторной графикой, реже — текста с формами, JavaScript'ом, 3D-графикой и другими типами элементов.

В приложениях Платформы "Мельница данных" для создания PDF-документов используется собственная библиотека PDFCreator.dll. С помощью библиотеки возможно прямое создание документов версии 1.3 . Создание PDF-документов осуществляется путем ввода предопределенных в библиотеке команд, которые в дальнейшем интерпретируются на основе языка описания страниц POSTSCRIPT.

        Все размеры графических объектов, размеры страниц, шрифтов и т.п. по умолчанию заданы в миллиметрах.
        Для удобства построения шаблона PDF-документа создана функция DrawGrid. При ее включении при отладке при создании шаблона будет отображена визуальная сетка с шагом 5 миллиметров.
C гридом

2. Методы

2.1. Свойства документа

Для создания и описания свойств PDF-документа в библиотеке PDFCreator.dll используется класс IPDFDocument, обладающий следующими свойствами:

  • Title (WideString) - заголовок документа. По умолчанию - пустая строка.
           
    Title = "DOC1"
  • CanEmbedFonts (WordBool) - Признак возможности построения PDF- документа со встроенными шрифтами (Embedded Fonts). В случае включения признака, все объявленные в скрипте шрифты будут включены в сборку документа и будут передаваться целиком вместе с документом. По умолчанию - False.
           
    CanEmbedFonts = True 
    CanEmbedFonts = False
  • CanCompress (WordBool) - признак сжатия документа при создании по собственным алгоритмам. По умолчанию - True.
           
    CanCompress = False 
    CanCompress = True
  • Author (WideString) - автор документа. По умолчанию - текущий пользователь ОС.
  • Subject (WideString) - описание документа. По умолчанию - пустая строка.
  • Keywords (WideString) - ключевые слова для поиска по документу. По умолчанию - пустая строка.
  • Creator (WideString) - приложение-родитель документа. Указывается в том случае, если документ был сконвертирован из другого формата.
  • PageCount (Integer) - свойство, содержащее общее количество страниц в документе.
  • Pages[Index: Integer]: IPDFPage - свойство документа, предназначенное для перебора страниц документа для совершения над ними однотипных действий.
           

    Пример использования:

    for I = 0 to PageCount - 1
      Pages(I).rectangle 10,10,10,10, false
    next
    Save "c:\pdf.pdf"

    Результат: На всех страницах документа будут нарисованы квадраты 10х10 мм.
  • procedure Save(Target: OleVariant) - процедура для сохранения документа PDF на жесткий диск сразу после создания.
           
    Save "c:\pdf.pdf"
    - сохранит документ в файл c:\pdf.pdf


2.2. Свойства страницы

Для создания страницы используется функция

function CreatePage(Parent: OleVariant): IPDFPage;

Параметр Parent указывает страницу-родителя для данной страницы. Если страницы- родителя быть не должно - формат вызова функции примет вид:

set page = CreatePage(Null)

Параметры страницы:

  • Title - заголовок страницы.
           
    page.Title = "Page name"
  • Width - ширина страницы, миллиметры
           
    page.Width = 80
  • Height - высота страницы, миллиметры
           
    page.Height = 80
  • DrawGrid - процедура, выводящая на страницу сетку с шагом 5 миллиметров для удобства отладки вида документа.
  • Perform - процедура, позволяющая выполнить дополнительные команды PostScript на странице.
            page.perform "1 0.7 0 0 k"
    page.perform "0 0 m"

2.2.1. Объявление цвета

Для объявления цвета объектов на странице используется цветовая модель R:G:B (Red:Green:Blue). Объявление цвета для выполнения последующих операций (цвет шрифта, цвет линии/фигуры) осуществляется процедурой

procedure SetColor(R: Integer; G: Integer; B: Integer);
Где параметры R, G, B - значения базисных цветов для выбранного цвета (от 0 до 255).

       
Цвет
R
G
B
Белый
255
255
255
+++
Черный
0
0
0
+++
Серый
190
190
190
+++
Синий
0
0
255
+++
Красный
255
0
0
+++
Зеленый
0
255
0
+++
       

Если предварительно цвет не был объявлен, используется цвет по умолчанию - черный (0,0,0)


2.3. Графика

2.3.1. Линии

Для отрисовки линий используется процедура

procedure Line(X1: Double; Y1: Double; X2: Double; Y2: Double);
Здесь:

  • X1 - координата начала линии по горизонтали в миллиметрах от верхнего левого угла листа.
  • Y1 - координата начала линии по вертикали в миллиметрах от верхнего левого угла листа.
  • X2 - координата конца линии по горизонтали в миллиметрах от верхнего левого угла листа.
  • Y2 - координата Конца линии по вертикали в миллиметрах от верхнего левого угла листа.

Для задания толщины линии используется свойство

property LineWidth: Double
Значение толщины задается в миллиметрах. Значение по умолчанию - минимально возможная единица рисования для устройства. Так для монитора - 1 pixel, для принтера - 1 dot (точка)

Для задания стиля отрисовки начала/окончания линии используется свойство property LineCap: TPDFLineCap
Возможные стили:
Значение свойства:
Отображение:
Описание:
0
Линия 0
Прямой срез точно по точкам начала и окончания линии (по умолчанию)
1
Линия 1
С закруглением
2
Линия 2
Прямой срез с продолжением линии на половину толщины линии

Объявление цвета линии.

        Две линии разной толщины, с разными окончаниями и цветами:
set page = CreatePage(Null)

page.DrawGrid

page.LineCap = 1

page.LineWidth = 2

page.Line 10, 10, 30, 30

page.LineWidth = 4

page.SetColor 255, 0, 0

page.LineCap = 2

page.Line 10, 30, 30, 10."I 


Результат:
2 линии

При необходимости соединения линий под углом в определенной точке можно задать тип соединения. Для объявления типа соединения используется свойство property LineJoin: TPDFLineJoin;
Типы соединения двух линий:
Значение свойства
Отображение
Описание
0
2 линии 0
С острым углом
1
2 линии 1
С закруглением
2
2 линии 2
С обрезанным углом

Пунктир

Для создания пунктира используется процедура отображения линии с предварительно объявленными дополнительными значениями.

Процедура procedure SetDash(DashArray: OleVariant; Phase: Integer); Здесь DashArray - массив значений в миллиметрах, указывающий последовательность чередования штрихов и пропусков на линии, Phase - смещение в миллиметрах по линии.

        Пример 1. Штрих 10 мм, Промежуток 5 мм, Смещения нет
Пример 2. Штрих 10 мм, Промежуток 5 мм, Смещение 5 мм
Пример 3. Различные значения штрихов и промежутков, Смещения нет
set page = CreatePage(Null)

page.DrawGrid

page.LineWidth = 3

page.SetDash Array(10, 5), 0

page.Line 10, 10, 100, 10

page.SetDash Array(10, 5), 5

page.Line 10, 20, 100, 20

page.SetDash Array(10, 5, 3, 2, 12, 20), 0

page.Line 10, 30, 100, 30

Результат:
Пунктир 1

Ломанная линия - здесь непрерывная линия, состоящая из нескольких прямых. Для отображения ломанной используется процедура procedure Poly(Points: OleVariant; Fill: WordBool), где Points - массив координат точек соединяемых прямыми, а Fill - признак заливки полученной замкнутой фигуры (если замкнута).

        Пример Звезда без заливки
set page = CreatePage(Null)

page.DrawGrid

page.LineWidth = 3

page.Poly  Array(10, 45, 100, 45, 27, 103, 55, 10, 82, 103, 10, 45), false

Результат:
Звезда
        Пример Звезда с заливкой
set page = CreatePage(Null)

page.DrawGrid

page.LineWidth = 3

page.Poly  Array(10, 45, 100, 45, 27, 103, 55, 10, 82, 103, 10, 45), true

Результат:
Звезда заливка

2.3.2. Прямоугольник

Rectangle (Прямоугольник) - для создания используется процедура:

procedure Rectangle(X1: Double; Y1: Double; Width: Double; Height: Double; Fill: WordBool);
Здесь:

  • X1 - координата верхнего левого угла прямоугольника по горизонтали в миллиметрах от верхнего левого угла листа шаблона.
  • Y1 - координата верхнего левого угла прямоугольника по вертикали в миллиметрах от верхнего левого угла листа шаблона.
  • Width - ширина прямоугольника с миллиметрах.
  • Height - высота прямоугольника с миллиметрах.
  • Fill - признак заливки прямоугольника (True/False). Если значение True то заливка производится объявленным заранее цветом (см. Объявление цвета). Если False - заливка не производится. Прямоугольник отрисовывается линиями с предварительно заданной толщиной. См. Линии
        Пример 1. Создание красного прямоугольника:
set page = CreatePage(Null)

page.SetColor 255, 0, 0

page.Rectangle 10, 15, 40, 20, True

page.DrawGrid
Результат:
Прямоугольник
Пример 2. Пустой прямоугольник без задания цвета:
set page = CreatePage(Null)

page.DrawGrid

page.Rectangle 12, 17, 42, 25, false

page.DrawGrid

Результат:
Прямоугольник false

Также существует возможность изменения стиля отображения углов прямоугольника. Для этого нужно использовать свойство property LineJoin: TPDFLineJoin;

Значение свойства
Отображение
Описание
0
2 линии 0
С острым углом
1
2 линии 1
С закруглением
2
2 линии 2
С обрезанным углом

Пример построения прямоугольников с различными типами соединения сторон:

       
set page = CreatePage(Null)

page.DrawGrid

page.LineWidth = 4

page.LineJoin = 0

page.Rectangle 10, 10, 20, 10, false

page.LineJoin = 1

page.Rectangle 40, 10, 20, 10, false

page.LineJoin = 2

page.Rectangle 70, 10, 20, 10, false


Результат:
3 прямоугольника

2.3.3. Вставка готовых изображений

Для вставки на создаваемую страницу готового изображения используется процедура procedure Image(const FileName: WideString; X: Double; Y: Double; Width: Double; Height: Double)

Параметры:

  • const FileName - имя файла изображения и путь к нему на жестком диске. Задается в кавычках.
  • X - координата левой верхней точки изображения по отношению к верхнему левому углу страницы по горизонтали в миллиметрах
  • Y - координата левой верхней точки изображения по отношению к верхнему левому углу страницы по вертикали в миллиметрах
  • Width - ширина изображения в миллиметрах
  • Height - высота изображения в миллиметрах.
       
set page = CreatePage(Null)
page.drawgrid
page.Image "c:\mill.bmp", 10,10, 30, 30

Результат:
Картинка

Вне зависимости от размера исходного изображения, при вставке изображения на создаваемую страницу оно будет растянуто по размерам, прописанным в процедуре.


2.3.4. Векторная графика

Язык PostScript, с помощью которого создаются векторные изображения для PDF-документа, поддерживает создание типичных примитивных объектов, таких как:

  • Прямые и ломанные линии
  • Многоугольники
  • Окружности и эллипсы
  • Кривые Безье
  • Текст

При создании векторного изображения на странице PDF-документа в приложениях Платформы, команды построения примитивных объектов PostScript передаются на исполнение при помощи процедуры Perform. Подробнее об операторах и командах PostScript для создания PDF-документов можно узнать на сайте Adobe


2.4. Шрифты

Шрифты, которые должны использоваться в создаваемом документе, должны быть предварительно объявлены. Для объявления используемых шрифтов используется функция
function CreateFont(const FontName: WideString; Size: Double; Bold: WordBool; Italic: WordBool): IPDFFont; где:

  • const FontName - имя шрифта, аналогичное имени объявляемого шрифта в операционной системе. В Функции объявляется в кавычках.
  • Size - размер шрифта в пунктах
  • Bold - признак начертания шрифта "жирный". Значения - True или False
  • Italic - признак начертания шрифта "курсив". Значения - True или False
        Примеры объявления шрифтов:
set font = page.createFont("Arial", 20, False, False)
set labelFont = page.createFont("Times New Roman", 16, False, True)
set dataFont = page.createFont("Tahoma", 18, True, False)
  

Для вывода текстовой информации на страницу используются процедуры:

  • procedure WriteLine(const LineText: WideString; X: Double; Y: Double);
    - используется для вывода текстовой строки
  • function WriteText(const AText: WideString; X: Double; Y: Double; Width: Double; Alignment: TPDFTextAlignment): Double;
    - используется для вывода текстового блока.

Параметры для procedure WriteLine :

  • const LineText - текстовая строка для вывода. Прописывается в кавычках. Будет выведена на страницу одной строкой.
  • X - координата верхней левой точки текстовой строки по горизонтали в миллиметрах.
  • Y - координата верхней левой точки текстовой строки по вертикали в миллиметрах.
        Примеры вывода текстов на страницу:
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 20, False, False)
set labelFont = page.createFont("Times New Roman", 16, False, True)
set dataFont = page.createFont("Tahoma", 18, True, False)
Font.WriteLine "Фамилия", 5, 2
Font.WriteLine "Имя", 5, 10
Font.WriteLine "Отчество", 5, 18
labelFont.WriteLine "Дата рождения", 5, 26
dataFont.WriteLine "Национальность", 5, 34
  

Результат:
Разные шрифты

Параметры для function WriteText :

  • const AText - текст для вывода на страницу. Прописывается в кавычках. Будет выведена на страницу в виде текстового блока.
  • X - координата верхней левой точки текстового блока по горизонтали в миллиметрах.
  • Y - координата верхней левой точки текстового блока по вертикали в миллиметрах.
  • Width - ширина текстового блока в миллиметрах
  • Alignment - тип выравнивания текста в текстовом блоке.
    Значение параметра
    Тип выравнивания
    0
    По левому краю
    1
    По правому краю
    2
    По центру
    3
    Выравнивание по ширине
        Примеры вывода текстовых блоков на страницу:
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 14, False, False)
set labelFont = page.createFont("Times New Roman", 12, False, True)
set dataFont = page.createFont("Tahoma", 11, True, False)
Q = font.WriteText ("Тест работы свойства для выравнивания текста в текстовом блоке для документа PDF, создаваемого на Платформе Мельница Данных", 5, 5, 100, 0)
Q = labelFont.WriteText ("Тест работы свойства для выравнивания текста в текстовом блоке для документа PDF, создаваемого на Платформе Мельница Данных", 5, 35, 100, 1)
Q = dataFont.WriteText ("Тест работы свойства для выравнивания текста в текстовом блоке для документа PDF, создаваемого на Платформе Мельница Данных", 5, 55, 100, 2)
Q = dataFont.WriteText ("Тест работы свойства для выравнивания текста в текстовом блоке для документа PDF, создаваемого на Платформе Мельница Данных", 5, 80, 100, 3)
  

Результат:
Выравнивание

Свойства шрифтов:

property Spacing: Double; - свойство, отвечающее за величину промежутка между буквами в слове. Задается в виде отклонения от промежутка между буквами по умолчанию для выбранного шрифта по горизонтальной оси в миллиметрах. Значение свойства равное "0" соответствует значению по умолчанию.

        Пример:
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 14, False, False)
set labelFont = page.createFont("Arial", 14, False, False)
set dataFont = page.createFont("Arial", 14, False, False)
font.Spacing = 0
labelFont.Spacing = 1
dataFont.Spacing = 2
font.WriteLine "Промежуток по умолчанию (0)", 5, 5
labelFont.WriteLine "Промежуток с отклонением (1 мм)", 5, 10
dataFont.WriteLine "Промежуток с отклонением (2 мм)", 5, 15
  

Результат:
Промежуток букв

property WordSpacing: Double; - свойство, отвечающее за величину промежутка между соседними словами. Задается в виде отклонения от промежутка между словами по умолчанию для выбранного шрифта по горизонтальной оси в миллиметрах. Значение свойства равное "0" соответствует значению по умолчанию.

        Пример:
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 14, False, False)
set labelFont = page.createFont("Arial", 14, False, False)
set dataFont = page.createFont("Arial", 14, False, False)
font.WordSpacing = 0
labelFont.WordSpacing = 2
dataFont.WordSpacing = 5
font.WriteLine "Промежуток по умолчанию (0)", 5, 5
labelFont.WriteLine "Промежуток с отклонением (2 мм)", 5, 10
dataFont.WriteLine "Промежуток с отклонением (5 мм)", 5, 15
  

Результат:
Промежуток слов

property Scaling: Double; - свойство, отвечающее за горизонтальное масштабирование букв используемого шрифта. Устанавливается в процентах. Горизонтальный масштаб по умолчанию - 100%.

        Пример:
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 14, False, False)
set labelFont = page.createFont("Arial", 14, False, False)
set dataFont = page.createFont("Arial", 14, False, False)
font.Scaling = 50
labelFont.Scaling = 100
dataFont.Scaling = 200
font.WriteLine "Сжатие (50)", 5, 5
labelFont.WriteLine "По умолчанию (100)", 5, 10
dataFont.WriteLine "Растягивание (150)", 5, 15
  

Результат:
Scaling

property RenderingMode: TPDFFontRenderingMode; - свойство, отвечающее за заливку букв используемого шрифта.
Типы заливки:
Значение параметра:
Отображение:
Описание:
0
Font Fill
Сплошная заливка (по умолчанию). Буква заливается сплошным цветом,
объявленным на данный момент.
1
Font Stroke
Только граница. Прорисовывается граница буквы. Тело остается незалитым.
2
Font FillStroke
Сначала заливка, потом граница. Граница прорисовывается всегда черным цветом.
Заливка осуществляется сплошным цветом, объявленным на данный момент.
3
Inv
Невидимый шрифт.

        Пример:
set page = CreatePage(Null)
set font = page.createFont("Arial", 20, False, False)
set labelFont = page.createFont("Arial", 20, False, False)
set dataFont = page.createFont("Arial", 20, False, False)
font.RenderingMode = 0
labelFont.RenderingMode = 1
dataFont.RenderingMode = 2
page.setColor 255, 0, 0
Q = font.WriteText ("Олимпиада", 5, 5, 50, 0)
Q = labelFont.WriteText ("Олимпиада", 5, 15, 50, 0)
Q = dataFont.WriteText ("Олимпиада", 5, 25, 50, 0)
  

Результат:
Заливка букв

property Rise: Double; - свойство, отвечающее за перемещение текста по вертикали.

       
set page = CreatePage(Null)
page.DrawGrid
set font = page.createFont("Arial", 20, False, False)
set labelFont = page.createFont("Arial", 7, False, False)
set dataFont = page.createFont("Arial", 7, False, False)
labelFont.rise = -17
dataFont.rise = -2
Q = font.WriteText ("Олимпиада", 5, 5, 50, 0)
Q = labelFont.WriteText ("Олимпиада", 44, 5, 50, 0)
Q = dataFont.WriteText ("Олимпиада", 44, 5, 50, 0)
  

Результат:
Rise

Для определения размеров текстовой строки используется процедура MeasureLine(const LineText: WideString; out Width: OleVariant; out Height: OleVariant);

Здесь:

  • LineText - исходный текст для размещения на странице
  • Width - возвращаемый параметр ширины текстового блока на странице
  • Height - возвращаемый параметр высоты текстового блока на странице
       
S = "шифр"
font.MeasureLine S, W, H
Q = font.WriteText(S, 139, 244 + ((23 - H) / 2), 40, 2)
  


Здесь для текста "Шифр" замеряется ширина и высота получившегося текстового блока. Затем полученные данные используются для корректного размещения текста на странице.

Для определения высоты текстового блока используется функция MeasureText(const AText: WideString; Width: Double): Double; safecall;

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

Здесь:

  • AText - исходный текст для размещения на странице. Прописывается в кавычках.
  • Width - задаваемая ширина текстового блока на странице в милиметрах.
       
S = "Текст для размещения на странице..."
Q = font.MeasureText(S, 139)
  
Здесь для текста "Текст для размещения на странице..." замеряется высота получившегося текстового блока. Затем полученные данные могут использоваться для корректного размещения текста на странице.

3. Порядок создания

Для создания шаблона PDF-документа необходимо в системной форме Платформы выбрать класс, к которому будет строиться документ. В подменю "Подпрограммы" вызвать контекстное меню и выбрать пункт "Создать шаблон отчета PDF". Заполнить необходимые поля и приступить к созданию скрипта в окне "Скрипт шаблона".

Конструктор
  1. Объявляем все переменные.
  2. Создаем страницы
  3. Устанавливаем все свойства документа и страниц
  4. Рисуем простые графические объекты
  5. Объявляем все используемые шрифты
  6. Расставляем постоянный текст на странице
  7. Расставляем переменный текст на странице
  8. Вставляем или создаем сложные графические объекты
        Пример документа PDF:
set LDataSet = createDataSet("TRoundAbiturSt")
'Объявление переменных
LDataSet.AddQueryItem 1, "ID", ID
LDataSet.AddQueryItem 0, "RoundComp$N"
LDataSet.AddQueryItem 0, "BachRound$N"
LDataSet.AddQueryItem 0, "LastName"
LDataSet.AddQueryItem 0, "FirstName"
LDataSet.AddQueryItem 0, "MiddleName"
LDataSet.AddQueryItem 0, "BirthDate"
LDataSet.AddQueryItem 0, "RegNumber"
LDataSet.AddQueryItem 0, "SecondStageCity$D"
LDataSet.AddQueryItem 0, "PhoneList"

'Присваивание переменным значений
OlympName = LDataSet.Field("RoundComp$N")
OlympClass = LDataSet.Field("BachRound$N")
LastName = LDataSet.Field("LastName")
FirstName = LDataSet.Field("FirstName")
MiddleName = LDataSet.Field("MiddleName")
if not IsNull(LDataSet.Field("BirthDate")) then
  BirthDate = LDataSet.Field("BirthDate")
else
  BirthDate = "(не задана)"
end if
RegNo = LDataSet.Field("RegNumber")
if not IsNull(LDataSet.Field("SecondStageCity$D")) then
  OlympCity = LDataSet.Field("SecondStageCity$D")
else
  OlympCity = "(не выбран город участия)"
end if
if not IsNull(LDataSet.Field("PhoneList")) then
  Phone = LDataSet.Field("PhoneList")
else
  Phone = ""
end if

'CanCompress = False - признак сжатия файла
set page = CreatePage(Null) ' создаем страницу
'Объявляем используемые шрифты
set font = page.createFont("Arial", 20, False, False)
set labelFont = page.createFont("Arial", 16, False, False)
set dataFont = page.createFont("Arial", 18, True, False)
set bigFont = page.createFont("Arial", 24, False, False)

'page.DrawGrid  - рисуем сетку для удобства отладки

page.LineWidth = 0.5 ' Установка толщины линии

' Рисуем прямоугольники
page.Rectangle 8, 12, 4, 4, True
page.Rectangle 190, 12, 4, 4, True

page.Rectangle 8, 273, 4, 4, True
page.Rectangle 105, 273, 4, 4, True
page.Rectangle 190, 273, 4, 4, True

'Выводим постоянный и переменный текст
Q = font.WriteText ("Межрегиональная олимпиада школьников", 12, 20, 178, 2)
Q = bigFont.WriteText (OlympName, 12, 45, 178, 2)
Q = bigFont.WriteText (OlympClass, 12, 56, 178, 2)

Q = font.WriteText ("Титульный лист", 12, 72, 178, 2)

labelFont.WriteLine "Фамилия", 25, 115 - 23
labelFont.WriteLine "Имя", 25, 123 - 23
labelFont.WriteLine "Отчество", 25, 131 - 23
labelFont.WriteLine "Дата", 25, 139 - 23
labelFont.WriteLine "рождения", 25, 145 - 23

labelFont.WriteLine "Регистрационный номер", 25, 169 - 30
labelFont.WriteLine "Город проведения", 25, 177 - 30
labelFont.WriteLine "Аудитория", 25, 185 - 30


labelFont.WriteLine "Дата", 25, 211
labelFont.WriteLine "Подпись", 25, 219
labelFont.WriteLine "Телефон", 25, 227


dataFont.WriteLine LastName, 63, 114 - 23
dataFont.WriteLine FirstName, 63, 122 - 23
dataFont.WriteLine MiddleName, 63, 130 - 23
dataFont.WriteLine BirthDate, 63, 141 - 23

dataFont.WriteLine RegNo, 100, 168 - 30
dataFont.WriteLine OlympCity, 100, 176 - 30

' Рисуем линии
page.line 100, 192 - 30, 150, 192 - 30
page.line 58, 218, 108, 218
page.line 58, 226, 108, 226
Q = dataFont.WriteText(Phone, 58, 226, 65, 0)



' Устанавливаем новый цвет
page.setColor 192, 192, 192

S = "шифр"
font.MeasureLine S, W, H  ' измеряем текстовый блок
Q = font.WriteText(S, 139, 244 + ((23 - H) / 2), 40, 2) ' располагаем текстовый
блок на странице

' Устанавливаем новый цвет
page.setColor 255, 0, 0
' Устанавливаем толщину линий в 1 пиксель
page.LineWidth = 0
' Рисуем линии по координатам
X = 139
Y = 267

page.line X, Y - 3, X, Y + 3
page.line X - 3, Y, X + 3, Y

X = X + 40
page.line X, Y - 3, X, Y + 3
page.line X - 3, Y, X + 3, Y


Y = Y - 23
page.line X, Y - 3, X, Y + 3
page.line X - 3, Y, X + 3, Y

X = X - 40
page.line X, Y - 3, X, Y + 3
page.line X - 3, Y, X + 3, Y

Результат:

Титул