Продолжаем цикл статей про динамический вывод данных из Fasteport. Посмотрим как можно вывести данные динамически, также моя дизайнерская душа не удержалась, и я немного занялся оформительством, добавил градиенты в отчет. Получилось так…
Имя и Фамилия это соответственно поля Name и Family из БД. Итак, приступим к динамическому выводу данных из БД при помощи FastReport.
Начали!
Создадим VCL приложение и разместим на нём следующие компоненты
К frxDBDataSet подключите любые данные, которые Вам необходимы. Я пользовался библиотекой FireDAC и подключил MySQL базу с запросом
1 |
select name,family from users |
Не буду останавливаться на подключении к БД и получении данных в FDQuery, покажу лишь, что я создал в отдельном DataModule
Вы можете подключиться по Вашей любимой технологии. Сосредоточимся на FastReport в данной статье.
Перед тем как мы напишем основной код, давайте примерно разметим в дизайнере, что мы будем делать.
Интересный момент в том – что мы можем проектировать как угодно наш отчет, но при генерации, благодаря инструкции
1 2 |
// Очищаем отчет frxReport1.Clear; |
он сотрется и загрузится тот, что мы сделаем динамически! На мой взгляд это удобное обстоятельство.
Как узнать о классах, которые нам нужны? На примере класса Gradient
Тут несколько вариантов. Первый и самый простой – в дизайнере создать тот элемент который нам нужен, выбрать его и посмотреть в объектном инспекторе.
Если юнита для этого класса нет в uses – Вы об этом узнаете через ошибку компиляции. В этом случае – просто найдите какой юнит нужен и добавьте в uses.
Всё остальное – дело техники!
Вот как я обработал нажатие на кнопку
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 |
procedure TMainForm.bShowDynamicReportClick(Sender: TObject); var Page: TfrxReportPage; Memo: TfrxMemoView; TitleBand:TFrxReportTitle; DataBand :TfrxMasterData; HeaderBand: TfrxHeader; Gradient:TFrxGradientView; FooterBand:TfrxFooter; begin frxReport1.Clear; Page := TfrxReportPage.Create(frxReport1); Page.CreateUniqueName; { устанавливаем размеры полей, бумаги и ориентацию по умолчанию } Page.SetDefaults; {СОЗДАЕМ BAND REPORT TITLE} TitleBand:=TFrxReportTitle.Create(Page); TitleBand.CreateUniqueName; TitleBand.Top:=0; TitleBand.Height:=40; {ДОБАВЛЯЕМ НА НЕГО MEMO} Memo:=TFrxMemoView.Create(TitleBand); Memo.CreateUniqueName; Memo.Text:='Привет! Это надпись на ReportTitle, градиент снизу также находится на ReportTitle '; Memo.Height:=20; Memo.Align:=baWidth; Memo.HAlign:=haCenter; Memo.Font.Style:=[fsBold,fsItalic]; Memo.Font.Color:=clGray; {ДОБАВЛЯЕМ ИСТОЧНИК ДАННЫХ} frxReport1.DataSets.Add(frxDBDataset1); {ДОБАВЛЯЕМ ГРАДИЕНТ} Gradient:=TFrxGradientView.Create(TitleBand); Gradient.CreateUniqueName; Gradient.SetBounds(0,21,TitleBand.Width,19); Gradient.BeginColor:=clWhite; Gradient.EndColor:=clBlue; Gradient.Visibility:=[vsPreview,vsExport,vsPrint]; //Gradient.Color:=$00C08080; Gradient.Style:=gsHorizontal; Gradient.Visible:=true; Gradient.Align:=baWidth;//Ключевой параметр,благодаря которому градиент появляется {ДОБАВЛЯЕМ HEADER для данных} HeaderBand := TfrxHeader.Create(Page); HeaderBand.CreateUniqueName; HeaderBand.Top:=TitleBand.Top+TitleBand.Height+1; HeaderBand.Height:=40; {ДОБАВЛЯЕМ ДАННЫЕ НА HEADER} memo:=TfrxMemoView.Create(HeaderBand); memo.CreateUniqueName; //Подключение к данным memo.Text:='Имя'; memo.SetBounds(0,20,100,20); memo.HAlign:=haCenter; memo.Font.Style:=[fsBold]; {ФАМИЛИЯ} memo:=TfrxMemoView.Create(HeaderBand); memo.CreateUniqueName; //Подключение к данным memo.Text:='Фамилия'; memo.SetBounds(101,20,100,20); memo.HAlign:=haCenter; memo.Font.Style:=[fsBold]; {ДОБАВЛЯЕМ DATABAND для данных} DataBand:=TfrxMasterData.Create(page); DataBand.CreateUniqueName; DataBand.DataSet:=frxDBDataset1; {Размещаем его на странице, так чтобы не было пересечений с предыдущим} DataBand.Top:=HeaderBand.Top+HeaderBand.Height+1; DataBand.Height:=40; {ДОБАВЛЯЕМ НА DATABAND данные} {ПОЛЕ NAME} memo:=TfrxMemoView.Create(DataBand); memo.CreateUniqueName; //Подключение к данным memo.DataSet:=frxDBDataset1; memo.DataField:='Name'; memo.SetBounds(0,20,100,20); memo.HAlign:=haCenter; {ПОЛЕ FAMILY} memo:=TfrxMemoView.Create(DataBand); memo.CreateUniqueName; //Подключение к данным memo.DataSet:=frxDBDataset1; memo.DataField:='Family'; memo.SetBounds(101,20,100,20); memo.HAlign:=haCenter; {ДОБАВЛЯЕМ FOOTER ДАННЫХ} FooterBand:=TfrxFooter.Create(Page); FooterBand.CreateUniqueName; FooterBand.Top:=DataBand.Top+DataBand.Height; FooterBand.Height:=40; {ПОДПИСЬ В ПОДВАЛЕ ДАННЫХ} memo:=TfrxMemoView.Create(FooterBand); memo.CreateUniqueName; //Подключение к данным memo.Text:='А это надпись из подвала данных на memo, градиент снизу тоже в подвале данных'; memo.SetBounds(0,0,FooterBand.Width,20); memo.HAlign:=haCenter; memo.Font.Color:=clGray; memo.Font.Style:=[fsBold,fsItalic]; memo.Align:=baWidth; {ДОБАВЛЯЕМ ГРАДИЕНТ НА FOOTER} Gradient:=TFrxGradientView.Create(FooterBand); Gradient.CreateUniqueName; Gradient.SetBounds(0,21,FooterBand.Width,19); Gradient.BeginColor:=clWhite; Gradient.EndColor:=clNavy; Gradient.Visibility:=[vsPreview,vsExport,vsPrint]; Gradient.Color:=$00C08080; Gradient.Style:=gsHorizontal; Gradient.Visible:=true; Gradient.Align:=baWidth;//Ключевой параметр,благодаря которому градиент появляется {ПОКАЗЫВАЕМ ОТЧЕТ} frxReport1.PreviewOptions.ThumbnailVisible:=true; frxReport1.ShowReport(); end; |
Выводы
Мы вывели данные из БД динамически, соблюдая основное правило для построения БЭНДОВ.
Они не должны пересекаться!!!
В остальном – принцип такой же как и при построении в дизайнере отчетов, при обилии данных число страниц будет увеличиваться.
Также мы посмотрели как можно узнать о классах тех или иных элементов. Единственное, что хотелось бы добавить – иногда может не хватать тех или иных юнитов, тогда их просто можно описать в uses, например, для градиента я прописал юнит frxGradient в uses. О нём я узнал случайно, из сети, но думаю есть какой-то способ – узнавать юниты классов системно. Об этом поговорим в других статьях.
Далее, в следующей статье, попробуем организовать вывод большого количества данных и посмотрим как “размножаются” страницы отчетов))